add initial implementation of explicit monitor (input|disk) control. some behaviour...
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 20 Oct 2011 18:50:29 +0000 (18:50 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 20 Oct 2011 18:50:29 +0000 (18:50 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@10256 d708f5d6-7413-0410-9779-e7cbd77b26cf

12 files changed:
gtk2_ardour/ardour3_styles.rc.in
gtk2_ardour/ardour3_widget_list.rc
gtk2_ardour/mixer_strip.cc
gtk2_ardour/route_ui.cc
gtk2_ardour/route_ui.h
libs/ardour/ardour/session.h
libs/ardour/ardour/track.h
libs/ardour/ardour/types.h
libs/ardour/audio_track.cc
libs/ardour/enums.cc
libs/ardour/session_rtevents.cc
libs/ardour/track.cc

index 5607e7c7df4011a051ead4ec05bb6544d5baa6dc..f29a4ef5f9123840a7869ab605a6c14b1971fdf8 100644 (file)
@@ -148,6 +148,27 @@ style "mixer_track_rec_enable_button_active" = "track_rec_enable_button_active"
        ythickness = 0
 }
 
+style "monitor_input_button" = "small_button"
+{
+        fg[NORMAL] = darker(@@COLPREFIX@_fg)
+        fg[PRELIGHT] = darker(@@COLPREFIX@_fg)
+        bg[NORMAL] = mix(0.1,@@COLPREFIX@_bright_indicator,darker(@@COLPREFIX@_bg))
+        bg[PRELIGHT] = mix(0.1,@@COLPREFIX@_bright_indicator,darker(@@COLPREFIX@_bg))
+        
+       fg[ACTIVE] = @@COLPREFIX@_fg
+       bg[ACTIVE] = @@COLPREFIX@_bright_indicator
+}
+
+style "monitor_disk_button" = "small_button"
+{
+        fg[NORMAL] = darker(@@COLPREFIX@_fg)
+        fg[PRELIGHT] = darker(@@COLPREFIX@_fg)
+        bg[NORMAL] = mix(0.1,@@COLPREFIX@_bright_indicator,darker(@@COLPREFIX@_bg))
+        bg[PRELIGHT] = mix(0.1,@@COLPREFIX@_bright_indicator,darker(@@COLPREFIX@_bg))
+        
+       fg[ACTIVE] = @@COLPREFIX@_fg
+       bg[ACTIVE] = @@COLPREFIX@_bright_indicator
+}
 
 style "solo_button" = "small_button"
 {
@@ -247,6 +268,18 @@ style "mixer_solo_button_active" = "solo_button_active"
        ythickness = 0
 }
 
+style "mixer_monitor_input_button" = "monitor_input_button"
+{
+       xthickness = 0
+       ythickness = 0
+}
+
+style "mixer_monitor_disk_button" = "monitor_disk_button"
+{
+       xthickness = 0
+       ythickness = 0
+}
+
 style "monitor_opt_button" = "small_button"
 {
         bg[NORMAL] = mix(0.1,@@COLPREFIX@_not_so_bright_indicator,@@COLPREFIX@_bg)
index d6d5ec8c03b0752992acb886b6c73e3c87b64ff2..ad2a6407259a86cf906585321ded4161faad5c57 100644 (file)
@@ -80,6 +80,8 @@ widget "*MixerSoloButton" style:highest "mixer_solo_button"
 widget "*MixerSoloButton-alternate" style:highest "mixer_solo_button_alternate"
 widget "*MixerSoloButton-alternate2" style:highest "mixer_solo_button_alternate2"
 widget "*MixerSoloButton-active" style:highest "mixer_solo_button_active"
+widget "*MixerMonitorInputButton" style:highest "mixer_monitor_input_button"
+widget "*MixerMonitorDiskButton" style:highest "mixer_monitor_disk_button"
 widget "*TrackLoopButton*" style:highest "track_loop_button"
 widget "*PanAutomationLineSelector*" style:highest "multiline_combo"
 widget "*EditorTimeButton*" style:highest "time_button"
index 15550f4cd451e283bfb5a19d85a67a19cdce7809..c069151bbea37fb84ac65c2225b787bc1f54ed06 100644 (file)
@@ -87,7 +87,7 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session* sess, bool in_mixer)
        , panners (sess)
        , button_table (3, 1)
        , solo_led_table (2, 2)
-       , middle_button_table (1, 2)
+       , middle_button_table (2, 2)
        , bottom_button_table (1, 2)
        , meter_point_label (_("pre"))
        , midi_input_enable_button (0)
@@ -112,7 +112,7 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session* sess, boost::shared_ptr<Route> rt
        , gpm (sess, 250)
        , panners (sess)
        , button_table (3, 1)
-       , middle_button_table (1, 2)
+       , middle_button_table (2, 2)
        , bottom_button_table (1, 2)
        , meter_point_label (_("pre"))
        , midi_input_enable_button (0)
@@ -184,6 +184,9 @@ MixerStrip::init ()
        mute_button->set_name ("MixerMuteButton");
        solo_button->set_name ("MixerSoloButton");
 
+       monitor_input_button->set_name ("MixerMonitorInputButton");
+       monitor_disk_button->set_name ("MixerMonitorInputButton");
+
         solo_isolated_led = manage (new LED);
         solo_isolated_led->show ();
         solo_isolated_led->set_diameter (6);
@@ -235,6 +238,8 @@ MixerStrip::init ()
        middle_button_table.set_spacings (0);
        middle_button_table.attach (*mute_button, 0, 1, 0, 1);
         middle_button_table.attach (*solo_button, 1, 2, 0, 1);
+       middle_button_table.attach (*monitor_input_button, 0, 1, 1, 2);
+        middle_button_table.attach (*monitor_disk_button, 1, 2, 1, 2);
 
        bottom_button_table.set_col_spacings (0);
        bottom_button_table.set_homogeneous (true);
@@ -396,6 +401,14 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
                global_vpacker.pack_start (*spacer, false, false);
        }
 
+       if (is_track()) {
+               monitor_input_button->show ();
+               monitor_disk_button->show ();
+       } else {
+               monitor_input_button->hide();
+               monitor_disk_button->hide ();
+       }
+
        if (is_midi_track()) {
                if (midi_input_enable_button == 0) {
                        Image* img = manage (new Image (get_icon (X_("midi_socket_small"))));
@@ -1643,6 +1656,8 @@ MixerStrip::drop_send ()
        rec_enable_button->set_sensitive (true);
        solo_isolated_led->set_sensitive (true);
        solo_safe_led->set_sensitive (true);
+       monitor_input_button->set_sensitive (true);
+       monitor_disk_button->set_sensitive (true);
 }
 
 void
@@ -1679,6 +1694,8 @@ MixerStrip::show_send (boost::shared_ptr<Send> send)
        rec_enable_button->set_sensitive (false);
        solo_isolated_led->set_sensitive (false);
        solo_safe_led->set_sensitive (false);
+       monitor_input_button->set_sensitive (false);
+       monitor_disk_button->set_sensitive (false);
 
        if (boost::dynamic_pointer_cast<InternalSend>(send)) {
                output_button.set_sensitive (false);
@@ -1714,6 +1731,8 @@ MixerStrip::set_button_names ()
        case Wide:
                rec_enable_button_label.set_text (_("Rec"));
                mute_button_label.set_text (_("Mute"));
+               monitor_input_button_label.set_text (_("In"));
+               monitor_disk_button_label.set_text (_("Disk"));
                if (_route && _route->solo_safe()) {
                        solo_button_label.set_text (X_("!"));
                } else {
@@ -1735,6 +1754,8 @@ MixerStrip::set_button_names ()
        default:
                rec_enable_button_label.set_text (_("R"));
                mute_button_label.set_text (_("M"));
+               monitor_input_button_label.set_text (_("I"));
+               monitor_disk_button_label.set_text (_("D"));
                if (_route && _route->solo_safe()) {
                        solo_button_label.set_text (X_("!"));
                        if (!Config->get_solo_control_is_listen_control()) {
index 90de21d8546f798690174a89add161f2b3fef709..6607da3942410d32b030e3c73205d2288d261ad0 100644 (file)
@@ -137,6 +137,22 @@ RouteUI::init ()
        // show_sends_button->set_self_managed (true);
        UI::instance()->set_tip (show_sends_button, _("make mixer strips show sends to this bus"), "");
 
+       monitor_input_button = manage (new BindableToggleButton ());
+       // monitor_input_button->set_self_managed (true);
+       monitor_input_button->set_name ("MonitorInputButton");
+       monitor_input_button->add (monitor_input_button_label);
+       monitor_input_button_label.show ();
+       UI::instance()->set_tip (monitor_input_button, _("Monitor input"), "");
+       monitor_input_button->set_no_show_all (true);
+
+       monitor_disk_button = manage (new BindableToggleButton ());
+       // monitor_disk_button->set_self_managed (true);
+       monitor_disk_button->set_name ("MonitorDiskButton");
+       monitor_disk_button->add (monitor_disk_button_label);
+       monitor_disk_button_label.show ();
+       UI::instance()->set_tip (monitor_disk_button, _("Monitor playback"), "");
+       monitor_disk_button->set_no_show_all (true);
+
        _session->SoloChanged.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::solo_changed_so_update_mute, this), gui_context());
        _session->TransportStateChange.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::check_rec_enable_sensitivity, this), gui_context());
        _session->RecordStateChanged.connect (_session_connections, invalidator (*this), boost::bind (&RouteUI::session_rec_enable_changed, this), gui_context());
@@ -153,6 +169,12 @@ RouteUI::init ()
        solo_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::solo_release), false);
        mute_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::mute_press), false);
        mute_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::mute_release), false);
+
+       monitor_input_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_press), false);
+       monitor_input_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_input_release), false);
+
+       monitor_disk_button->signal_button_press_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_press), false);
+       monitor_disk_button->signal_button_release_event().connect (sigc::mem_fun(*this, &RouteUI::monitor_disk_release), false);
 }
 
 void
@@ -211,7 +233,7 @@ RouteUI::set_route (boost::shared_ptr<Route> rp)
                boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
 
                t->RecordEnableChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_rec_enable_changed, this), gui_context());
-
+               
                rec_enable_button->show();
                rec_enable_button->set_controllable (t->rec_enable_control());
 
@@ -224,6 +246,11 @@ RouteUI::set_route (boost::shared_ptr<Route> rp)
 
        }
 
+       if (is_track()) {
+               boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
+               t->MonitoringChanged.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::monitoring_changed, this), gui_context());
+       }
+
        mute_button->unset_flags (Gtk::CAN_FOCUS);
        solo_button->unset_flags (Gtk::CAN_FOCUS);
 
@@ -555,6 +582,96 @@ RouteUI::rec_enable_press(GdkEventButton* ev)
        return true;
 }
 
+void
+RouteUI::monitoring_changed ()
+{
+       boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
+
+       if (!t) {
+               return;
+       }
+
+       MonitorChoice mc = t->monitoring();
+
+       if (mc & MonitorInput) {
+               monitor_input_button->set_active (true);
+       } else {
+               monitor_input_button->set_active (false);
+       }
+
+       if (mc & MonitorDisk) {
+               monitor_disk_button->set_active (true);
+       } else {
+               monitor_disk_button->set_active (false);
+       }
+}
+
+bool
+RouteUI::monitor_input_press(GdkEventButton* ev)
+{
+       return true;
+}
+
+bool
+RouteUI::monitor_input_release(GdkEventButton* ev)
+{
+       return monitor_release (ev, MonitorInput);
+}
+
+bool
+RouteUI::monitor_disk_press (GdkEventButton* ev)
+{
+       return true;
+}
+
+bool
+RouteUI::monitor_disk_release (GdkEventButton* ev)
+{
+       return monitor_release (ev, MonitorDisk);
+}
+
+bool
+RouteUI::monitor_release (GdkEventButton* ev, MonitorChoice monitor_choice)
+{      
+       if (ev->button != 1) {
+               return false;
+       }
+
+       boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
+
+       if (!t) {
+               return true;
+       }
+
+       MonitorChoice mc;
+       boost::shared_ptr<RouteList> rl;
+       
+       /* XXX for now, monitoring choices are orthogonal. cue monitoring 
+          will follow in 3.X but requires mixing the input and playback (disk)
+          signal together, which requires yet more buffers.
+       */
+
+       if (t->monitoring() & monitor_choice) {
+               mc = MonitorChoice (t->monitoring() & ~monitor_choice);
+       } else {
+               /* this line will change when the options are non-orthogonal */
+               // mc = MonitorChoice (t->monitoring() | monitor_choice);
+               mc = monitor_choice;
+       }
+
+       if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::TertiaryModifier))) {       
+               rl = _session->get_routes ();
+
+       } else {
+               rl.reset (new RouteList);
+               rl->push_back (route());
+       }
+
+       _session->set_monitoring (rl, mc, Session::rt_cleanup, true);           
+
+       return true;
+}
+
 void
 RouteUI::build_record_menu ()
 {
index e5f240ff5be14a39d2ff653dae06223a8241007c..d084ec696a6e50120ceea5a5a1ffe34c14def482 100644 (file)
@@ -94,6 +94,8 @@ class RouteUI : public virtual AxisView
        BindableToggleButton* solo_button;
        BindableToggleButton* rec_enable_button; /* audio tracks */
        BindableToggleButton* show_sends_button; /* busses */
+       BindableToggleButton* monitor_input_button;
+       BindableToggleButton* monitor_disk_button;
 
         LED* solo_safe_led;
         LED* solo_isolated_led;
@@ -101,6 +103,8 @@ class RouteUI : public virtual AxisView
        Gtk::Label solo_button_label;
        Gtk::Label mute_button_label;
        Gtk::Label rec_enable_button_label;
+       Gtk::Label monitor_input_button_label;
+       Gtk::Label monitor_disk_button_label;
 
        void send_blink (bool);
        sigc::connection send_blink_connection;
@@ -121,6 +125,13 @@ class RouteUI : public virtual AxisView
        bool show_sends_press(GdkEventButton*);
        bool show_sends_release(GdkEventButton*);
 
+       bool monitor_release(GdkEventButton*, ARDOUR::MonitorChoice);
+       bool monitor_input_press(GdkEventButton*);
+       bool monitor_input_release(GdkEventButton*);
+       bool monitor_disk_press(GdkEventButton*);
+       bool monitor_disk_release(GdkEventButton*);
+       void monitoring_changed ();
+
        void step_gain_up ();
        void step_gain_down ();
        void page_gain_up ();
index d96d8fc828c1ddaf53c692cb74a244682b6705a6..ad42ee768ba15852b6b512a735a19cebb9ebaa93 100644 (file)
@@ -37,6 +37,7 @@
 #include <glibmm/thread.h>
 
 #include "pbd/error.h"
+#include "pbd/event_loop.h"
 #include "pbd/rcu.h"
 #include "pbd/statefuldestructible.h"
 #include "pbd/signals.h"
@@ -622,6 +623,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        void set_record_enabled (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
        void set_solo_isolated (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
        void set_exclusive_input_active (boost::shared_ptr<Route> rt, bool others_on);
+       void set_monitoring (boost::shared_ptr<RouteList>, MonitorChoice, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
 
        PBD::Signal1<void,bool> SoloActive;
        PBD::Signal0<void> SoloChanged;
@@ -1454,10 +1456,16 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        static int ask_about_playlist_deletion (boost::shared_ptr<Playlist>);
 
        /* realtime "apply to set of routes" operations */
-       SessionEvent* get_rt_event (
-               boost::shared_ptr<RouteList> rl, bool yn,
-               SessionEvent::RTeventCallback after, bool group_override,
-               void (Session::*method) (boost::shared_ptr<RouteList>, bool, bool));
+       template<typename T> SessionEvent*
+               get_rt_event (boost::shared_ptr<RouteList> rl, T targ, SessionEvent::RTeventCallback after, bool group_override,
+                             void (Session::*method) (boost::shared_ptr<RouteList>, T, bool)) {
+               SessionEvent* ev = new SessionEvent (SessionEvent::RealTimeOperation, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
+               ev->rt_slot = boost::bind (method, this, rl, targ, group_override);
+               ev->rt_return = after;
+               ev->event_loop = PBD::EventLoop::get_event_loop_for_thread ();
+               
+               return ev;
+       }
 
        void rt_set_solo (boost::shared_ptr<RouteList>, bool yn, bool group_override);
        void rt_set_just_one_solo (boost::shared_ptr<RouteList>, bool yn, bool /* ignored*/ );
@@ -1465,6 +1473,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        void rt_set_listen (boost::shared_ptr<RouteList>, bool yn, bool group_override);
        void rt_set_solo_isolated (boost::shared_ptr<RouteList>, bool yn, bool group_override);
        void rt_set_record_enabled (boost::shared_ptr<RouteList>, bool yn, bool group_override);
+       void rt_set_monitoring (boost::shared_ptr<RouteList>, MonitorChoice, bool group_override);
 
        /** temporary list of Diskstreams used only during load of 2.X sessions */
        std::list<boost::shared_ptr<Diskstream> > _diskstreams_2X;
index 6e7d9ae1e57da0ee8033ceafaf5c9b28959cb187..9aefc4f403cfb9da807a92eade842cb4e2b7c8cd 100644 (file)
@@ -48,6 +48,10 @@ class Track : public Route, public PublicDiskstream
        virtual bool can_use_mode (TrackMode /*m*/, bool& /*bounce_required*/) { return false; }
        PBD::Signal0<void> TrackModeChanged;
 
+       virtual void set_monitoring (MonitorChoice);
+       MonitorChoice monitoring() const { return _monitoring; }
+       PBD::Signal0<void> MonitoringChanged;
+
        virtual int no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
                             bool state_changing, bool can_record);
 
@@ -161,9 +165,10 @@ class Track : public Route, public PublicDiskstream
        virtual XMLNode& state (bool full) = 0;
 
        boost::shared_ptr<Diskstream> _diskstream;
-       MeterPoint  _saved_meter_point;
-       TrackMode   _mode;
-       bool        _needs_butler;
+       MeterPoint    _saved_meter_point;
+       TrackMode     _mode;
+       bool          _needs_butler;
+       MonitorChoice _monitoring;
 
        //private: (FIXME)
        struct FreezeRecordProcessorInfo {
index 9579c87b7bfb60b8a4b34203e06a61ab0d015286..e2daf1a76c3d413ce8e617730b7b647aeb84fbd2 100644 (file)
@@ -358,6 +358,13 @@ namespace ARDOUR {
                ExternalMonitoring
        };
 
+       enum MonitorChoice {
+               MonitorAuto = 0,
+               MonitorInput = 0x1,
+               MonitorDisk = 0x2,
+               MonitorCue = 0x4,
+       };
+
        enum PFLPosition {
                /** PFL signals come from before pre-fader processors */
                PFLFromBeforeProcessors,
index 14870cb72dc18b2649bd78c814dcb5bd1e10e296..b22b28d277cc8a2830584b6bdb30fa611561bc81 100644 (file)
@@ -403,12 +403,16 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram
                _input->process_input (_meter, start_frame, end_frame, nframes);
        }
 
-       if (diskstream->record_enabled() && !can_record && !_session.config.get_auto_input()) {
-
+       if ((_monitoring & MonitorInput) || 
+           (!(_monitoring & MonitorDisk) && 
+            (diskstream->record_enabled() && !can_record && !_session.config.get_auto_input()))) {
+               
                /* not actually recording, but we want to hear the input material anyway,
                   at least potentially (depending on monitoring options)
                 */
 
+               cerr << name() << " do the passthru thing with monitoring = " << enum_2_string (_monitoring) << endl;
+
                passthru (start_frame, end_frame, nframes, false);
 
        } else if ((b = diskstream->playback_buffer(0)) != 0) {
@@ -734,3 +738,5 @@ AudioTrack::bounceable () const
 {
        return n_inputs().n_audio() >= n_outputs().n_audio();
 }
+
+       
index 8fd008c11948e273303963c8fa6ebcacfb0bfb4a..dc3a115bf5964f22e2369d620aba307e285dfa83 100644 (file)
@@ -66,6 +66,7 @@ setup_enum_writer ()
        RegionPoint _RegionPoint;
        Placement _Placement;
        MonitorModel _MonitorModel;
+       MonitorChoice _MonitorChoice;
        PFLPosition _PFLPosition;
        AFLPosition _AFLPosition;
        RemoteModel _RemoteModel;
@@ -228,6 +229,12 @@ setup_enum_writer ()
        REGISTER_ENUM (ExternalMonitoring);
        REGISTER (_MonitorModel);
 
+       REGISTER_ENUM (MonitorInput);
+       REGISTER_ENUM (MonitorDisk);
+       REGISTER_ENUM (MonitorAuto);
+       REGISTER_ENUM (MonitorCue);
+       REGISTER_BITS (_MonitorChoice);
+
        REGISTER_ENUM (PFLFromBeforeProcessors);
        REGISTER_ENUM (PFLFromAfterProcessors);
        REGISTER (_PFLPosition);
index ce40c5ce9e5b4f787f8c77521411ba682cf4a34b..ca1ee319c7d93e32c7497c2a52dbf84547977148 100644 (file)
@@ -32,16 +32,25 @@ using namespace PBD;
 using namespace ARDOUR;
 using namespace Glib;
 
-SessionEvent*
-Session::get_rt_event (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override,
-                      void (Session::*method) (boost::shared_ptr<RouteList>, bool, bool))
+void
+Session::set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, SessionEvent::RTeventCallback after, bool group_override)
+{
+       queue_event (get_rt_event (rl, mc, after, group_override, &Session::rt_set_monitoring));
+}
+
+void
+Session::rt_set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, bool /* group_override */)
 {
-       SessionEvent* ev = new SessionEvent (SessionEvent::RealTimeOperation, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
-       ev->rt_slot = boost::bind (method, this, rl, yn, group_override);
-       ev->rt_return = after;
-       ev->event_loop = EventLoop::get_event_loop_for_thread ();
+       for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
+               if (!(*i)->is_hidden()) {
+                       boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
+                       if (t) {
+                               t->set_monitoring (mc);
+                       }
+               }
+       }
 
-       return ev;
+       set_dirty();
 }
 
 void
index 5c9bcc747de49df8507b92b46c097a168e3ca58c..b21a02b4902372c3abc4e4cb612ce3c6d6ebbd5c 100644 (file)
@@ -43,6 +43,7 @@ Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, Data
        : Route (sess, name, flag, default_type)
         , _saved_meter_point (_meter_point)
         , _mode (mode)
+       , _monitoring (MonitorAuto)
        , _rec_enable_control (new RecEnableControllable(*this))
 {
        _freeze_record.state = NoFreeze;
@@ -640,36 +641,31 @@ Track::adjust_capture_buffering ()
 bool
 Track::send_silence () const
 {
-        /*
-          ADATs work in a strange way..
-          they monitor input always when stopped.and auto-input is engaged.
-
-          Other machines switch to input on stop if the track is record enabled,
-          regardless of the auto input setting (auto input only changes the
-          monitoring state when the transport is rolling)
-        */
-
         bool send_silence;
 
-        if (!Config->get_tape_machine_mode()) {
-                /*
-                  ADATs work in a strange way..
-                  they monitor input always when stopped.and auto-input is engaged.
+        if (Config->get_tape_machine_mode()) {
+
+                /* ADATs work in a strange way..
+                  they monitor input always when stopped.and auto-input is engaged.
                 */
+               
                 if ((Config->get_monitoring_model() == SoftwareMonitoring)
-                    && (_session.config.get_auto_input () || _diskstream->record_enabled())) {
-                        send_silence = false;
+                    && ((_monitoring & MonitorInput) || (_diskstream->record_enabled()))) {
+                       send_silence = false;
                 } else {
                         send_silence = true;
                 }
+               
+               
         } else {
-                /*
-                  Other machines switch to input on stop if the track is record enabled,
-                  regardless of the auto input setting (auto input only changes the
-                  monitoring state when the transport is rolling)
+               
+                /* Other machines switch to input on stop if the track is record enabled,
+                  regardless of the auto input setting (auto input only changes the
+                  monitoring state when the transport is rolling)
                 */
+               
                 if ((Config->get_monitoring_model() == SoftwareMonitoring)
-                    && _diskstream->record_enabled()) {
+                    && (!(_monitoring & MonitorDisk) && (_session.config.get_auto_input () || _diskstream->record_enabled()))) {
                         send_silence = false;
                 } else {
                         send_silence = true;
@@ -732,6 +728,14 @@ Track::check_initial_delay (framecnt_t nframes, framecnt_t& transport_frame)
 
        }
 
-       return nframes;
+       return nframes; 
 }
 
+void
+Track::set_monitoring (MonitorChoice mc)
+{
+       if (mc !=  _monitoring) {
+               _monitoring = mc;
+               MonitoringChanged (); /* EMIT SIGNAL */
+       }
+}