Fix a problem where VST automation data wasn't getting written (if the adjustments...
[ardour.git] / libs / ardour / track.cc
index 1426c3926c4f947a52f71ccf0e3e947680d336e0..e99d07f0475f139f46828899bf09b3108f78869f 100644 (file)
@@ -100,9 +100,9 @@ Track::state (bool full)
        root.add_property (X_("saved-meter-point"), enum_2_string (_saved_meter_point));
        root.add_child_nocopy (_rec_enable_control->get_state());
        root.add_child_nocopy (_diskstream->get_state ());
-       
+
        return root;
-}      
+}
 
 int
 Track::set_state (const XMLNode& node, int version)
@@ -140,7 +140,7 @@ Track::set_state (const XMLNode& node, int version)
                        }
                }
        }
-       
+
        const XMLProperty* prop;
 
        if ((prop = node.property (X_("monitoring"))) != 0) {
@@ -196,7 +196,7 @@ Track::RecEnableControl::set_value (double val)
        if (!t) {
                return;
        }
-       
+
        t->set_record_enabled (val >= 0.5 ? true : false, this);
 }
 
@@ -207,7 +207,7 @@ Track::RecEnableControl::get_value () const
        if (!t) {
                return 0;
        }
-       
+
        return (t->record_enabled() ? 1.0 : 0.0);
 }
 
@@ -232,6 +232,10 @@ Track::can_record()
 void
 Track::prep_record_enabled (bool yn, void *src)
 {
+       if (yn && record_safe ()) {
+           return;
+       }
+
        if (!_session.writable()) {
                return;
        }
@@ -251,7 +255,7 @@ Track::prep_record_enabled (bool yn, void *src)
        }
 
        bool will_follow;
-       
+
        if (yn) {
                will_follow = _diskstream->prep_record_enable ();
        } else {
@@ -272,6 +276,10 @@ Track::prep_record_enabled (bool yn, void *src)
 void
 Track::set_record_enabled (bool yn, void *src)
 {
+       if (_diskstream->record_safe ()) {
+           return;
+       }
+
        if (!_session.writable()) {
                return;
        }
@@ -290,6 +298,31 @@ Track::set_record_enabled (bool yn, void *src)
        _rec_enable_control->Changed ();
 }
 
+bool
+Track::record_safe () const
+{
+       return _diskstream && _diskstream->record_safe ();
+}
+
+void
+Track::set_record_safe (bool yn, void *src)
+{
+       if (!_session.writable()) { /* REQUIRES REVIEW */
+               return;
+       }
+
+       if (_freeze_record.state == Frozen) { /* REQUIRES REVIEW */
+               return;
+       }
+
+       if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_recenable()) {
+               _route_group->apply (&Track::set_record_safe, yn, _route_group);
+               return;
+       }
+
+       _diskstream->set_record_safe (yn);
+}
+
 void
 Track::parameter_changed (string const & p)
 {
@@ -441,12 +474,12 @@ Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
                be_silent = false;
                break;
        }
-       
+
        //if we have an internal generator, let it play regardless of monitoring state
        if (_have_internal_generator) {
                be_silent = false;
        }
-       
+
        _amp->apply_gain_automation (false);
 
        /* if have_internal_generator, or .. */
@@ -495,7 +528,7 @@ Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
        } else {
 
                BufferSet& bufs = _session.get_route_buffers (n_process_buffers());
-               
+
                fill_buffers_with_input (bufs, _input, nframes);
 
                if (_meter_point == MeterInput) {
@@ -558,6 +591,7 @@ Track::set_diskstream (boost::shared_ptr<Diskstream> ds)
        ds->PlaylistChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_playlist_changed, this));
        diskstream_playlist_changed ();
        ds->RecordEnableChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_record_enable_changed, this));
+       ds->RecordSafeChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_record_safe_changed, this));
        ds->SpeedChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_speed_changed, this));
        ds->AlignmentStyleChanged.connect_same_thread (*this, boost::bind (&Track::diskstream_alignment_style_changed, this));
 }
@@ -574,6 +608,12 @@ Track::diskstream_record_enable_changed ()
        RecordEnableChanged (); /* EMIT SIGNAL */
 }
 
+void
+Track::diskstream_record_safe_changed ()
+{
+       RecordSafeChanged (); /* EMIT SIGNAL */
+}
+
 void
 Track::diskstream_speed_changed ()
 {
@@ -890,15 +930,74 @@ Track::adjust_capture_buffering ()
         }
 }
 
+#ifdef USE_TRACKS_CODE_FEATURES
+
+/* This is the Tracks version of Track::monitoring_state().
+ *
+ * Ardour developers: try to flag or fix issues if parts of the libardour API
+ * change in ways that invalidate this
+ */
+
 MonitorState
 Track::monitoring_state () const
 {
        /* Explicit requests */
-       
+
        if (_monitoring & MonitorInput) {
                return MonitoringInput;
        }
-               
+
+       if (_monitoring & MonitorDisk) {
+               return MonitoringDisk;
+       }
+
+       /* This is an implementation of the truth table in doc/monitor_modes.pdf;
+          I don't think it's ever going to be too pretty too look at.
+       */
+
+       // GZ: NOT USED IN TRACKS
+       //bool const auto_input = _session.config.get_auto_input ();
+       //bool const software_monitor = Config->get_monitoring_model() == SoftwareMonitoring;
+       //bool const tape_machine_mode = Config->get_tape_machine_mode ();
+
+       bool const roll = _session.transport_rolling ();
+       bool const track_rec = _diskstream->record_enabled ();
+       bool session_rec = _session.actively_recording ();
+
+       if (track_rec) {
+
+               if (!session_rec && roll) {
+                       return MonitoringDisk;
+               } else {
+                       return MonitoringInput;
+               }
+
+       } else {
+
+               if (roll) {
+                       return MonitoringDisk;
+               }
+       }
+
+       return MonitoringSilence;
+}
+
+#else
+
+/* This is the Ardour/Mixbus version of Track::monitoring_state().
+ *
+ * Tracks developers: do NOT modify this method under any circumstances.
+ */
+
+MonitorState
+Track::monitoring_state () const
+{
+       /* Explicit requests */
+
+       if (_monitoring & MonitorInput) {
+               return MonitoringInput;
+       }
+
        if (_monitoring & MonitorDisk) {
                return MonitoringDisk;
        }
@@ -947,7 +1046,7 @@ Track::monitoring_state () const
                        } else {
                                return MonitoringDisk;
                        }
-                       
+
                }
        }
 
@@ -955,6 +1054,8 @@ Track::monitoring_state () const
        return MonitoringSilence;
 }
 
+#endif
+
 void
 Track::maybe_declick (BufferSet& bufs, framecnt_t nframes, int declick)
 {
@@ -1010,7 +1111,7 @@ Track::check_initial_delay (framecnt_t nframes, framepos_t& transport_frame)
 
        }
 
-       return nframes; 
+       return nframes;
 }
 
 void