MCP: a fistful of improvements. probably best to just try it and see what it broken...
authorPaul Davis <paul@linuxaudiosystems.com>
Sun, 22 Apr 2012 02:15:24 +0000 (02:15 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Sun, 22 Apr 2012 02:15:24 +0000 (02:15 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@12053 d708f5d6-7413-0410-9779-e7cbd77b26cf

16 files changed:
libs/ardour/ardour/control_protocol_manager.h
libs/ardour/control_protocol_manager.cc
libs/ardour/session.cc
libs/surfaces/control_protocol/control_protocol/control_protocol.h
libs/surfaces/mackie/controls.cc
libs/surfaces/mackie/gui.cc
libs/surfaces/mackie/mackie_control_protocol.cc
libs/surfaces/mackie/mackie_control_protocol.h
libs/surfaces/mackie/mcp_buttons.cc
libs/surfaces/mackie/pot.cc
libs/surfaces/mackie/pot.h
libs/surfaces/mackie/strip.cc
libs/surfaces/mackie/strip.h
libs/surfaces/mackie/surface.cc
libs/surfaces/mackie/surface.h
libs/surfaces/mackie/surface_port.cc

index ad5bb3166eb339d7fd1cf9b61d0221ed0396dc7c..19abbaf6bed5e7610fca75007c230cb888fef98b 100644 (file)
@@ -62,10 +62,11 @@ class ControlProtocolManager : public PBD::Stateful, public ARDOUR::SessionHandl
        void discover_control_protocols ();
        void foreach_known_protocol (boost::function<void(const ControlProtocolInfo*)>);
        void load_mandatory_protocols ();
+       void midi_connectivity_established ();
 
        ControlProtocol* instantiate (ControlProtocolInfo&);
        int              teardown (ControlProtocolInfo&);
-
+       
        std::list<ControlProtocolInfo*> control_protocol_info;
 
        static const std::string state_node_name;
index 6a8dd77d55c21a890c14f912c06640bba2c37599..876091fa7d7ef3055155dac44b60383690b33774 100644 (file)
@@ -401,3 +401,13 @@ ControlProtocolManager::instance ()
 
        return *_instance;
 }
+
+void
+ControlProtocolManager::midi_connectivity_established ()
+{
+       Glib::Mutex::Lock lm (protocols_lock);
+
+       for (list<ControlProtocol*>::iterator p = control_protocols.begin(); p != control_protocols.end(); ++p) {
+               (*p)->midi_connectivity_established ();
+       }
+}
index a7fc6740c29664bac3ef3f060d1b042a9aebc3b8..5744b55c65dd62eb8278c4ee248a31668526ade2 100644 (file)
@@ -537,11 +537,17 @@ Session::when_engine_running ()
 
        BootMessage (_("Setup signal flow and plugins"));
 
+       /* this will cause the CPM to instantiate any protocols that are in use
+        * (or mandatory), which will pass it this Session, and then call
+        * set_state() on each instantiated protocol to match stored state.
+        */
+
        ControlProtocolManager::instance().set_session (this);
 
        /* This must be done after the ControlProtocolManager set_session above,
           as it will set states for ports which the ControlProtocolManager creates.
        */
+
        MIDI::Manager::instance()->set_port_states (Config->midi_port_states ());
 
        /* And this must be done after the MIDI::Manager::set_port_states as
@@ -550,6 +556,12 @@ Session::when_engine_running ()
 
        hookup_io ();
 
+       /* Let control protocols know that we are now all connected, so they
+        * could start talking to surfaces if they want to.
+        */
+
+       ControlProtocolManager::instance().midi_connectivity_established ();
+
        if (_is_new && !no_auto_connect()) {
                Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock());
                auto_connect_master_bus ();
index 89e9e6c4d5baab14af44864757606d9e95a9d90f..5401c985993468a04e8005bd059e3c3a4013b756 100644 (file)
@@ -54,6 +54,8 @@ class ControlProtocol : virtual public sigc::trackable, public PBD::Stateful, pu
 
        virtual void route_list_changed () {}
 
+       virtual void midi_connectivity_established () {}
+
        PBD::Signal0<void> ActiveChanged;
 
        /* signals that a control protocol can emit and other (presumably graphical)
index 29d8d165ce106310ea75625ce0cd2b2eb1896cdb..e5b8a28ab76ad78252f6f30de22c45331ef2722d 100644 (file)
@@ -92,24 +92,33 @@ Control::set_control (boost::shared_ptr<AutomationControl> ac)
 void
 Control::set_value (float val)
 {
-       normal_ac->set_value (normal_ac->interface_to_internal (val));
+       if (normal_ac) {
+               normal_ac->set_value (normal_ac->interface_to_internal (val));
+       }
 }
 
 float
 Control::get_value ()
 {
+       if (!normal_ac) {
+               return 0.0f;
+       }
        return normal_ac->internal_to_interface (normal_ac->get_value());
 }
 
 void
 Control::start_touch (double when)
 {
-       return normal_ac->start_touch (when);
+       if (normal_ac) {
+               return normal_ac->start_touch (when);
+       }
 }
        
 void
 Control::stop_touch (double when, bool mark)
 {
-       return normal_ac->stop_touch (when, mark);
+       if (normal_ac) {
+               return normal_ac->stop_touch (when, mark);
+       }
 }
        
index e9c95ddec9d2e4ebc86c57907e246fe516ff84aa..2136a64d22621ef508a98ba6bf3a2c2631390991 100644 (file)
@@ -33,6 +33,8 @@
 #include "gtkmm2ext/utils.h"
 #include "gtkmm2ext/actions.h"
 
+#include "ardour/rc_configuration.h"
+
 #include "mackie_control_protocol.h"
 #include "device_info.h"
 #include "gui.h"
@@ -477,8 +479,10 @@ MackieControlProtocolGUI::surface_combo_changed ()
 void
 MackieControlProtocolGUI::profile_combo_changed ()
 {
-       _cp.set_profile (_profile_combo.get_active_text());
-       refresh_function_key_editor ();
-}
+       string profile = _profile_combo.get_active_text();
 
+       _cp.set_profile (profile);
+       ARDOUR::Config->set_mackie_device_profile (profile);
 
+       refresh_function_key_editor ();
+}
index e7403e636d57f9ecc58066dd69b8e3f92c3015eb..c74acd06f06b2949857b1f9fea1b283f008b182e 100644 (file)
@@ -1,5 +1,6 @@
 /*
        Copyright (C) 2006,2007 John Anderson
+       Copyright (C) 2012 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
@@ -114,11 +115,6 @@ MackieControlProtocol::MackieControlProtocol (Session& session)
        set_device (Config->get_mackie_device_name());
        set_profile (Config->get_mackie_device_profile());
 
-       AudioEngine::instance()->PortConnectedOrDisconnected.connect (
-               audio_engine_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::port_connected_or_disconnected, this, _2, _4, _5),
-               this
-               );
-
        TrackSelectionChanged.connect (gui_connections, MISSING_INVALIDATOR, ui_bind (&MackieControlProtocol::gui_track_selection_changed, this, _1), this);
 
        _instance = this;
@@ -165,6 +161,14 @@ MackieControlProtocol::thread_init ()
        }
 }
 
+void
+MackieControlProtocol::midi_connectivity_established ()
+{
+       /* may need to tell surfaces because they may need to wake up the
+        * device 
+        */
+}
+
 // go to the previous track.
 // Assume that get_sorted_routes().size() > route_table.size()
 void 
@@ -307,10 +311,6 @@ MackieControlProtocol::switch_banks (uint32_t initial, bool force)
        _current_initial_bank = initial;
        _current_selected_track = -1;
 
-       for (Surfaces::iterator si = surfaces.begin(); si != surfaces.end(); ++si) {
-               (*si)->drop_routes ();
-       }
-
        // Map current bank of routes onto each surface(+strip)
 
        if (_current_initial_bank <= sorted.size()) {
@@ -473,6 +473,8 @@ MackieControlProtocol::update_surfaces()
                return;
        }
 
+
+
        // do the initial bank switch to connect signals
        // _current_initial_bank is initialised by set_state
        switch_banks (_current_initial_bank, true);
@@ -727,7 +729,7 @@ MackieControlProtocol::update_timecode_display()
 
        boost::shared_ptr<Surface> surface = surfaces.front();
 
-       if (surface->type() != mcu || !surface->has_timecode_display()) {
+       if (surface->type() != mcu || !_device_info.has_timecode_display()) {
                return;
        }
 
@@ -886,26 +888,6 @@ MackieControlProtocol::bundles ()
        return b;
 }
 
-void
-MackieControlProtocol::port_connected_or_disconnected (string a, string b, bool connected)
-{
-       /* If something is connected to one of our output ports, send MIDI to update the surface
-          to whatever state it should have.
-       */
-
-       if (!connected) {
-               return;
-       }
-
-       for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
-               string const n = AudioEngine::instance()->make_port_name_non_relative ((*s)->port().output_port().name ());
-               if (a == n || b == n) {
-                       update_surfaces ();
-                       return;
-               }
-       }
-}
-
 void
 MackieControlProtocol::do_request (MackieControlUIRequest* req)
 {
index d1075e25cec7e628de31a2b0f468bd0c33511552..2b29cde63a377246b0fb1e740fccdf7317a63b75 100644 (file)
@@ -229,10 +229,7 @@ class MackieControlProtocol
        int stop ();
 
        void thread_init ();
-
-       /* handling function key presses */
-
-       void f_press (uint32_t fn);
+       void midi_connectivity_established ();
 
   private:
 
@@ -282,7 +279,6 @@ class MackieControlProtocol
        ButtonMap                 button_map;
 
        void create_surfaces ();
-       void port_connected_or_disconnected (std::string, std::string, bool);
        bool periodic();
        void build_gui ();
        bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);
index 4032785a3be480bf8b2aec7ca3ad209f61f8e291..616cdc1e763451be2a208113a81921da97a9fe5a 100644 (file)
@@ -438,9 +438,7 @@ MackieControlProtocol::frm_left_press (Button &)
        // can use first_mark_before/after as well
        unsigned long elapsed = _frm_left_last.restart();
 
-       Location * loc = session->locations()->first_location_before (
-               session->transport_frame()
-       );
+       Location * loc = session->locations()->first_location_before (session->transport_frame());
 
        // allow a quick double to go past a previous mark
        if (session->transport_rolling() && elapsed < 500 && loc != 0) {
@@ -454,6 +452,8 @@ MackieControlProtocol::frm_left_press (Button &)
        // move to the location, if it's valid
        if (loc != 0) {
                session->request_locate (loc->start(), session->transport_rolling());
+       } else {
+               session->request_locate (session->locations()->session_range_location()->start(), session->transport_rolling());
        }
 
        return on;
@@ -473,6 +473,8 @@ MackieControlProtocol::frm_right_press (Button &)
        
        if (loc != 0) {
                session->request_locate (loc->start(), session->transport_rolling());
+       } else {
+               session->request_locate (session->locations()->session_range_location()->end(), session->transport_rolling());
        }
                
        return on;
@@ -530,7 +532,11 @@ MackieControlProtocol::record_release (Button &)
 LedState 
 MackieControlProtocol::rewind_press (Button &)
 {
-       rewind ();
+       if (_modifier_state == MODIFIER_CONTROL) {
+               goto_start ();
+       } else {
+               rewind ();
+       }
        return none;
 }
 
@@ -543,7 +549,11 @@ MackieControlProtocol::rewind_release (Button &)
 LedState 
 MackieControlProtocol::ffwd_press (Button &)
 {
-       ffwd ();
+       if (_modifier_state == MODIFIER_CONTROL) {
+               goto_end();
+       } else {
+               ffwd ();
+       }
        return none;
 }
 
@@ -664,20 +674,9 @@ MackieControlProtocol::enter_release (Button &)
        return off;
 }
 
-void
-MackieControlProtocol::f_press (uint32_t fn)
-{
-#if 0
-       string action = f_action (0);
-       if (!action.empty()) {
-               access_action (action);
-       }
-#endif
-}
 LedState
 MackieControlProtocol::F1_press (Button &) 
 { 
-       f_press (0);
        return off; 
 }
 LedState
@@ -688,7 +687,6 @@ MackieControlProtocol::F1_release (Button &)
 LedState
 MackieControlProtocol::F2_press (Button &) 
 { 
-       f_press (1);
        return off; 
 }
 LedState
@@ -699,7 +697,6 @@ MackieControlProtocol::F2_release (Button &)
 LedState
 MackieControlProtocol::F3_press (Button &) 
 { 
-       f_press (2);
        return off; 
 }
 LedState
@@ -710,7 +707,6 @@ MackieControlProtocol::F3_release (Button &)
 LedState
 MackieControlProtocol::F4_press (Button &) 
 { 
-       f_press (3);
        return off; 
 }
 LedState
@@ -721,7 +717,6 @@ MackieControlProtocol::F4_release (Button &)
 LedState
 MackieControlProtocol::F5_press (Button &) 
 { 
-       f_press (4);
        return off; 
 }
 LedState
@@ -732,7 +727,6 @@ MackieControlProtocol::F5_release (Button &)
 LedState
 MackieControlProtocol::F6_press (Button &) 
 { 
-       f_press (5);
        return off; 
 }
 LedState
@@ -743,7 +737,6 @@ MackieControlProtocol::F6_release (Button &)
 LedState
 MackieControlProtocol::F7_press (Button &) 
 { 
-       f_press (6);
        return off; 
 }
 LedState
index 63b0424297d8ed45edcb59a17348d7c81658cebf..ceec0ea940160c9c3d0510ddbf04a4c840379a31 100644 (file)
@@ -38,46 +38,23 @@ Pot::factory (Surface& surface, int id, const char* name, Group& group)
 }
 
 MidiByteArray
-Pot::set_mode (Pot::Mode m)
-{
-       mode = m;
-       return update_message ();
-}
-
-MidiByteArray
-Pot::set_onoff (bool onoff)
-{
-       on = onoff;
-       return update_message ();
-}
-
-MidiByteArray
-Pot::set_all (float val, bool onoff, Mode m)
-{
-       position = val;
-       on = onoff;
-       mode = m;
-       return update_message ();
-}
-
-MidiByteArray
-Pot::update_message ()
+Pot::set (float val, bool onoff, Mode mode)
 {
        // TODO do an exact calc for 0.50? To allow manually re-centering the port.
 
        // center on or off
-       MIDI::byte msg =  (position > 0.45 && position < 0.55 ? 1 : 0) << 6;
+       MIDI::byte msg =  (val > 0.45 && val < 0.55 ? 1 : 0) << 6;
        
        // mode
-       msg |=  (mode << 4);
+       msg |=  (onoff << 4);
        
-       // position, but only if off hasn't explicitly been set
+       // val, but only if off hasn't explicitly been set
 
-       if  (on) {
+       if  (onoff) {
                if (mode == spread) {
-                       msg +=  (lrintf (position * 6) + 1) & 0x0f; // 0b00001111
+                       msg +=  (lrintf (val * 6) + 1) & 0x0f; // 0b00001111
                } else {
-                       msg +=  (lrintf (position * 10.0) + 1) & 0x0f; // 0b00001111
+                       msg +=  (lrintf (val * 10.0) + 1) & 0x0f; // 0b00001111
                }
        }
 
index f8e94a3391fdbb81be8ee4dbaacf5be6f584e8fc..3bbf0f33f43b6b9bb3649b666bf4deaef99dcd1b 100644 (file)
@@ -38,25 +38,13 @@ public:
        };
 
        Pot (int id, std::string name, Group & group)
-               : Control (id, name, group)
-               , position (0.0)
-               , mode (dot)
-               , on (true) {}
+               : Control (id, name, group) {}
 
-       MidiByteArray set_mode (Mode);
-       MidiByteArray set_onoff (bool);
-       MidiByteArray set_all (float, bool, Mode);
-
-       MidiByteArray zero() { return set_all (0.0, on, mode); }
-       
-       MidiByteArray update_message ();
+       MidiByteArray set (float, bool, Mode);
+       MidiByteArray zero() { return set (0.0, false, Pot::spread); }
 
        static Control* factory (Surface&, int id, const char*, Group&);
 
-  private:
-       float position;
-       Mode mode;
-       bool on;
 };
 
 }
index 4f4a96ebdceeaeff3a62f3a77d248e2616218318..bf3ff0d588fe4dea19269061fe6a8f6e0d6a4416 100644 (file)
@@ -137,7 +137,7 @@ Strip::add (Control & control)
 }
 
 void
-Strip::set_route (boost::shared_ptr<Route> r)
+Strip::set_route (boost::shared_ptr<Route> r, bool with_messages)
 {
        if (_controls_locked) {
                return;
@@ -216,39 +216,16 @@ Strip::set_route (boost::shared_ptr<Route> r)
                        }
                }
        }
-
-       current_pot_modes.push_back (Input);
-       current_pot_modes.push_back (Output);
-
-       if (_route->nth_send (0) != 0) {
-               current_pot_modes.push_back (Send1);
-       }
-       if (_route->nth_send (1) != 0) {
-               current_pot_modes.push_back (Send2);
-       }
-       if (_route->nth_send (2) != 0) {
-               current_pot_modes.push_back (Send3);
-       }
-       if (_route->nth_send (3) != 0) {
-               current_pot_modes.push_back (Send4);
-       }
-       if (_route->nth_send (4) != 0) {
-               current_pot_modes.push_back (Send5);
-       }
-       if (_route->nth_send (5) != 0) {
-               current_pot_modes.push_back (Send6);
-       }
-       if (_route->nth_send (6) != 0) {
-               current_pot_modes.push_back (Send7);
-       }
-       if (_route->nth_send (7) != 0) {
-               current_pot_modes.push_back (Send8);
-       }
 }
 
 void 
 Strip::notify_all()
 {
+       if (!_route) {
+               zero ();
+               return;
+       }
+
        notify_solo_changed ();
        notify_mute_changed ();
        notify_gain_changed ();
@@ -301,8 +278,6 @@ Strip::notify_route_deleted ()
 void 
 Strip::notify_gain_changed (bool force_update)
 {
-       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("gain changed for strip %1, flip mode %2\n", _index, _surface->mcp().flip_mode()));
-
        if (_route) {
                
                Control* control;
@@ -313,35 +288,29 @@ Strip::notify_gain_changed (bool force_update)
                        control = _fader;
                }
 
-               if (!control->in_use()) {
-
-                       boost::shared_ptr<AutomationControl> ac = _route->gain_control();
-
-                       float gain_coefficient = ac->get_value();
-                       float normalized_position = ac->internal_to_interface (gain_coefficient);
-
-                       if (force_update || normalized_position != _last_gain_position_written) {
 
-
-                               if (_surface->mcp().flip_mode()) {
-                                       _surface->write (_vpot->set_all (normalized_position, true, Pot::wrap));
-                                       do_parameter_display (GainAutomation, gain_coefficient);
-                               } else {
-                                       _surface->write (_fader->set_position (normalized_position));
-                                       do_parameter_display (GainAutomation, gain_coefficient);
+               boost::shared_ptr<AutomationControl> ac = _route->gain_control();
+               
+               float gain_coefficient = ac->get_value();
+               float normalized_position = ac->internal_to_interface (gain_coefficient);
+               
+               if (force_update || normalized_position != _last_gain_position_written) {
+                       
+                       if (_surface->mcp().flip_mode()) {
+                               if (!control->in_use()) {
+                                       _surface->write (_vpot->set (normalized_position, true, Pot::wrap));
                                }
-
-                               queue_display_reset (2000);
-                               _last_gain_position_written = normalized_position;
-                               
+                               do_parameter_display (GainAutomation, gain_coefficient);
                        } else {
-                               DEBUG_TRACE (DEBUG::MackieControl, "value is stale, no message sent\n");
+                               if (!control->in_use()) {
+                                       _surface->write (_fader->set_position (normalized_position));
+                               }
+                               do_parameter_display (GainAutomation, gain_coefficient);
                        }
-               } else {
-                       DEBUG_TRACE (DEBUG::MackieControl, "fader in use, no message sent\n");
+
+                       queue_display_reset (2000);
+                       _last_gain_position_written = normalized_position;
                }
-       } else {
-               DEBUG_TRACE (DEBUG::MackieControl, "no route or no fader\n");
        }
 }
 
@@ -361,7 +330,7 @@ Strip::notify_property_changed (const PropertyChange& what_changed)
                } else {
                        line1 = PBD::short_version (fullname, 6);
                }
-               
+
                _surface->write (display (0, line1));
        }
 }
@@ -402,7 +371,7 @@ Strip::notify_panner_azi_changed (bool force_update)
                                        _surface->write (_fader->set_position (pos));
                                        do_parameter_display (PanAzimuthAutomation, pos);
                                } else {
-                                       _surface->write (_vpot->set_all (pos, true, Pot::dot));
+                                       _surface->write (_vpot->set (pos, true, Pot::dot));
                                        do_parameter_display (PanAzimuthAutomation, pos);
                                }
 
@@ -449,7 +418,7 @@ Strip::notify_panner_width_changed (bool force_update)
                                        _surface->write (_fader->set_position (pos));
                                        do_parameter_display (PanWidthAutomation, pos);
                                } else {
-                                       _surface->write (_vpot->set_all (pos, true, Pot::spread));
+                                       _surface->write (_vpot->set (pos, true, Pot::spread));
                                        do_parameter_display (PanWidthAutomation, pos);
                                }
 
@@ -725,19 +694,15 @@ Strip::update_meter ()
        }
 }
 
-MidiByteArray
+void
 Strip::zero ()
 {
-       MidiByteArray retval;
-
        for (Group::Controls::const_iterator it = _controls.begin(); it != _controls.end(); ++it) {
-               retval << (*it)->zero ();
+               _surface->write ((*it)->zero ());
        }
 
-       retval << blank_display (0);
-       retval << blank_display (1);
-       
-       return retval;
+       _surface->write (blank_display (0));
+       _surface->write (blank_display (1));
 }
 
 MidiByteArray
@@ -778,8 +743,6 @@ Strip::display (uint32_t line_number, const std::string& line)
        // sysex trailer
        retval << MIDI::eox;
        
-       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("MackieMidiBuilder::strip_display midi: %1\n", retval));
-
        return retval;
 }
 
@@ -901,7 +864,12 @@ Strip::clear_display_reset ()
 void
 Strip::reset_display ()
 {
-       _surface->write (display (1, vpot_mode_string()));
+       if (_route) {
+               _surface->write (display (1, vpot_mode_string()));
+       } else {
+               _surface->write (blank_display (1));
+       }
+               
        clear_display_reset ();
 }
                         
@@ -991,7 +959,7 @@ Strip::next_pot_mode ()
                /* do not change vpot mode while in flipped mode */
                DEBUG_TRACE (DEBUG::MackieControl, "not stepping pot mode - in flip mode\n");
                _surface->write (display (1, "Flip"));
-               queue_display_reset (2000);
+               queue_display_reset (1000);
                return;
        }
 
@@ -1050,13 +1018,11 @@ Strip::set_vpot_mode (PotMode m)
                                if (pannable) {
                                        _fader->set_control (pannable->pan_azimuth_control);
                                }
-                               _vpot->set_mode (Pot::boost_cut);
                                _vpot_mode = Gain;
                        } else {
                                /* gain to fader, pan azi to vpot */
                                _fader->set_control (_route->gain_control());
                                if (pannable) {
-                                       _vpot->set_mode (Pot::dot);
                                        _vpot->set_control (pannable->pan_azimuth_control);
                                }
                        }
@@ -1071,13 +1037,11 @@ Strip::set_vpot_mode (PotMode m)
                                if (pannable) {
                                        _fader->set_control (pannable->pan_width_control);
                                }
-                               _vpot->set_mode (Pot::boost_cut);
                                _vpot_mode = Gain;
                        } else {
                                /* gain to fader, pan width to vpot */
                                _fader->set_control (_route->gain_control());
                                if (pannable) {
-                                       _vpot->set_mode (Pot::spread);
                                        _vpot->set_control (pannable->pan_width_control);
                                }
                        }
index a8213f6f89543da767caff0950a9637a02888273..dfa0fbf33a52aed1e3cd32749d77b9fccb580100 100644 (file)
@@ -58,7 +58,7 @@ public:
        void add (Control & control);
        int index() const { return _index; } // zero based
        
-       void set_route (boost::shared_ptr<ARDOUR::Route>);
+       void set_route (boost::shared_ptr<ARDOUR::Route>, bool with_messages = true);
 
        // call all signal handlers manually
        void notify_all();
@@ -71,7 +71,8 @@ public:
 
        MidiByteArray display (uint32_t line_number, const std::string&);
        MidiByteArray blank_display (uint32_t line_number);
-       MidiByteArray zero ();
+
+       void zero ();
 
        void flip_mode_changed (bool notify=false);
 
index 08b0355d5cb9bc5c88807501dc013a49dbb9d649..053761fd3e1d77379266a5b5309573a580230c62 100644 (file)
@@ -63,7 +63,7 @@ Surface::Surface (MackieControlProtocol& mcp, const std::string& device_name, ui
        , _stype (stype)
        , _number (number)
        , _name (device_name)
-       , _active (true)
+       , _active (false)
        , _connected (false)
        , _jog_wheel (0)
 {
@@ -91,17 +91,6 @@ Surface::Surface (MackieControlProtocol& mcp, const std::string& device_name, ui
        
        connect_to_signals ();
 
-       /* wakey wakey */
-
-       MidiByteArray wakeup (7, MIDI::sysex, 0x00, 0x00, 0x66, 0x14, 0x00, MIDI::eox);
-       _port->write (wakeup);
-       wakeup[4] = 0x15; /* wakup Mackie XT */
-       _port->write (wakeup);
-       wakeup[4] = 0x10; /* wakupe Logic Control */
-       _port->write (wakeup);
-       wakeup[4] = 0x11; /* wakeup Logic Control XT */
-       _port->write (wakeup);
-
        DEBUG_TRACE (DEBUG::MackieControl, "Surface::init finish\n");
 }
 
@@ -109,12 +98,7 @@ Surface::~Surface ()
 {
        DEBUG_TRACE (DEBUG::MackieControl, "Surface: destructor\n");
 
-       // faders to minimum
-       write_sysex (0x61);
-       // All LEDs off
-       write_sysex (0x62);
-       // Reset (reboot into offline mode)
-       // _write_sysex (0x63);
+       zero_all ();
 
        // delete groups
        for (Groups::iterator it = groups.begin(); it != groups.end(); ++it) {
@@ -127,7 +111,8 @@ Surface::~Surface ()
        }
        
        delete _jog_wheel;
-       delete _port;
+
+       /* don't delete the port, because we want its output to remain queued */
 }
 
 const MidiByteArray& 
@@ -261,17 +246,11 @@ Surface::blank_jog_ring ()
        if (control) {
                Pot* pot = dynamic_cast<Pot*> (control);
                if (pot) {
-                       _port->write (pot->set_onoff (false));
+                       _port->write (pot->set (0.0, false, Pot::spread));
                }
        }
 }
 
-bool 
-Surface::has_timecode_display () const
-{
-       return false;
-}
-
 float
 Surface::scrub_scaling_factor () const
 {
@@ -413,7 +392,6 @@ Surface::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count
 {
        MidiByteArray bytes (count, raw_bytes);
 
-
        DEBUG_TRACE (DEBUG::MackieControl, string_compose ("handle_midi_sysex: %1\n", bytes));
 
        /* always save the device type ID so that our outgoing sysex messages
@@ -434,7 +412,15 @@ Surface::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count
                if (bytes[4] == 0x10 || bytes[4] == 0x11) {
                        write_sysex (host_connection_query (bytes));
                } else {
-                       _active = true;
+                       if (!_active) {
+                               _active = true;
+                               std::cerr << "Surface " << _number << " Now active!\n";
+                               zero_controls ();
+                               for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
+                                       (*s)->notify_all ();
+                               }
+                               update_view_mode_display ();
+                       }
                }
                break;
 
@@ -541,14 +527,6 @@ Surface::write_sysex (MIDI::byte msg)
        _port->write (buf);
 }
 
-void
-Surface::drop_routes ()
-{
-       for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
-               (*s)->set_route (boost::shared_ptr<Route>());
-       }
-}
-
 uint32_t
 Surface::n_strips () const
 {
@@ -569,9 +547,21 @@ Surface::zero_all ()
 {
        // TODO turn off Timecode displays
 
+       std::cerr << "Surface " << number() << " ZERO\n";
+
        // zero all strips
        for (Strips::iterator it = strips.begin(); it != strips.end(); ++it) {
-               _port->write ((*it)->zero());
+               (*it)->zero();
+       }
+
+       zero_controls ();
+}
+
+void
+Surface::zero_controls ()
+{
+       if (_stype != mcu || !_mcp.device_info().has_global_controls()) {
+               return;
        }
 
        // turn off global buttons and leds
@@ -585,9 +575,11 @@ Surface::zero_all ()
                }
        }
 
-       // any hardware-specific stuff
-       // clear 2-char display
-       _port->write (two_char_display ("  "));
+       if (_number == 0 && _mcp.device_info().has_two_character_display()) {
+               // any hardware-specific stuff
+               // clear 2-char display
+               _port->write (two_char_display ("aa"));
+       }
 
        // and the led ring for the master strip
        blank_jog_ring ();
@@ -599,13 +591,14 @@ Surface::periodic (uint64_t now_usecs)
        for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
                (*s)->periodic (now_usecs);
        }
-
 }
 
 void
 Surface::write (const MidiByteArray& data) 
 {
-       _port->write (data);
+       if (_active) {
+               _port->write (data);
+       }
 }
 
 void 
@@ -639,13 +632,15 @@ Surface::map_routes (const vector<boost::shared_ptr<Route> >& routes)
        vector<boost::shared_ptr<Route> >::const_iterator r;
        Strips::iterator s;
 
-       for (s = strips.begin(); s != strips.end(); ++s) {
-               (*s)->set_route (boost::shared_ptr<Route>());
-       }
-
        for (r = routes.begin(), s = strips.begin(); r != routes.end() && s != strips.end(); ++r, ++s) {
                (*s)->set_route (*r);
        }
+
+       for (; s != strips.end(); ++s) {
+               (*s)->set_route (boost::shared_ptr<Route>());
+       }
+
+
 }
 
 static char translate_seven_segment (char achar)
@@ -662,7 +657,7 @@ static char translate_seven_segment (char achar)
 MidiByteArray 
 Surface::two_char_display (const std::string & msg, const std::string & dots)
 {
-       if (_stype != mcu) {
+       if (_stype != mcu || !_mcp.device_info().has_two_character_display()) {
                return MidiByteArray();
        }
 
@@ -690,7 +685,7 @@ Surface::two_char_display (unsigned int value, const std::string & /*dots*/)
 void 
 Surface::display_timecode (const std::string & timecode, const std::string & timecode_last)
 {
-       if (has_timecode_display()) {
+       if (_active && _mcp.device_info().has_timecode_display()) {
                _port->write (timecode_display (timecode, timecode_last));
        }
 }
@@ -752,6 +747,10 @@ Surface::update_view_mode_display ()
        string text;
        Button* button = 0;
 
+       if (!_active) {
+               return;
+       }
+
        switch (_mcp.view_mode()) {
        case MackieControlProtocol::Mixer:
                _port->write (two_char_display ("Mx"));
@@ -807,3 +806,19 @@ Surface::gui_selection_changed (ARDOUR::RouteNotificationListPtr routes)
        }
 }
 
+void
+Surface::say_hello ()
+{
+       /* wakey wakey */
+
+       MidiByteArray wakeup (7, MIDI::sysex, 0x00, 0x00, 0x66, 0x14, 0x00, MIDI::eox);
+       _port->write (wakeup);
+       wakeup[4] = 0x15; /* wakup Mackie XT */
+       _port->write (wakeup);
+       wakeup[4] = 0x10; /* wakupe Logic Control */
+       _port->write (wakeup);
+       wakeup[4] = 0x11; /* wakeup Logic Control XT */
+       _port->write (wakeup);
+
+       zero_all ();
+}
index b5a887bbc7e7746107c3b3e0ab0475c15c69e8b7..747abad0cfefffce444fd9841d265aa2c6c914ae 100644 (file)
@@ -45,6 +45,8 @@ public:
        uint32_t number() const { return _number; }
        const std::string& name() { return _name; }
 
+       void say_hello ();
+
        bool active() const { return _active; }
        void drop_routes ();
 
@@ -102,12 +104,12 @@ public:
                
        /// called from MackieControlProtocol::zero_all to turn things off
        void zero_all ();
+       void zero_controls ();
 
        /// turn off leds around the jog wheel. This is for surfaces that use a pot
        /// pretending to be a jog wheel.
        void blank_jog_ring ();
 
-       bool has_timecode_display() const;
        void display_timecode (const std::string & /*timecode*/, const std::string & /*timecode_last*/);
 
        /**
index ebc2ab1117499fec010ba3354b13a163e1dcb1c6..be080fa44b6eb0e2bcd0eae6aa83657abf9bf03e 100644 (file)
@@ -101,7 +101,7 @@ SurfacePort::write (const MidiByteArray & mba)
        }
 
        DEBUG_TRACE (DEBUG::MackieControl, string_compose ("port %1 write %2\n", output_port().name(), mba));
-       
+
        int count = output_port().write (mba.bytes().get(), mba.size(), 0);
 
        if  (count != (int)mba.size()) {