Return silence from read_from_sources() if we try to read a channel that our source...
[ardour.git] / libs / ardour / track.cc
index 2ef3c85b4a7c4679462c950419e3040e3d44fcfd..0ad59d1b31b93db50340e3a095044a5a9def0cea 100644 (file)
 #include "pbd/error.h"
 
 #include "ardour/amp.h"
-#include "ardour/audioplaylist.h"
-#include "ardour/audioregion.h"
-#include "ardour/audiosource.h"
 #include "ardour/debug.h"
 #include "ardour/delivery.h"
 #include "ardour/diskstream.h"
 #include "ardour/io_processor.h"
 #include "ardour/meter.h"
+#include "ardour/playlist.h"
 #include "ardour/port.h"
 #include "ardour/processor.h"
 #include "ardour/route_group_specialized.h"
@@ -44,7 +42,6 @@ Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, Data
         , _saved_meter_point (_meter_point)
         , _mode (mode)
        , _monitoring (MonitorAuto)
-       , _rec_enable_control (new RecEnableControllable(*this))
 {
        _freeze_record.state = NoFreeze;
         _declickable = true;
@@ -64,6 +61,15 @@ Track::init ()
                 return -1;
         }
 
+       boost::shared_ptr<Route> rp (shared_from_this());
+       boost::shared_ptr<Track> rt = boost::dynamic_pointer_cast<Track> (rp);
+       _rec_enable_control = boost::shared_ptr<RecEnableControl> (new RecEnableControl(rt));
+       _rec_enable_control->set_flags (Controllable::Toggle);
+
+       /* don't add rec_enable_control to controls because we don't want it to
+        * appear as an automatable parameter
+        */
+
         return 0;
 }
 
@@ -195,23 +201,34 @@ Track::freeze_state() const
        return _freeze_record.state;
 }
 
-Track::RecEnableControllable::RecEnableControllable (Track& s)
-       : Controllable (X_("recenable"), Controllable::Toggle), track (s)
+Track::RecEnableControl::RecEnableControl (boost::shared_ptr<Track> t)
+       : AutomationControl (t->session(), RecEnableAutomation, boost::shared_ptr<AutomationList>(), X_("recenable"))
+       , track (t)
 {
+       boost::shared_ptr<AutomationList> gl(new AutomationList(Evoral::Parameter(RecEnableAutomation)));
+       set_list (gl);
 }
 
 void
-Track::RecEnableControllable::set_value (double val)
+Track::RecEnableControl::set_value (double val)
 {
-       bool bval = ((val >= 0.5) ? true: false);
-       track.set_record_enabled (bval, this);
+       boost::shared_ptr<Track> t = track.lock ();
+       if (!t) {
+               return;
+       }
+       
+       t->set_record_enabled (val >= 0.5 ? true : false, this);
 }
 
 double
-Track::RecEnableControllable::get_value (void) const
+Track::RecEnableControl::get_value () const
 {
-       if (track.record_enabled()) { return 1.0; }
-       return 0.0;
+       boost::shared_ptr<Track> t = track.lock ();
+       if (!t) {
+               return 0;
+       }
+       
+       return (t->record_enabled() ? 1.0 : 0.0);
 }
 
 bool
@@ -312,7 +329,15 @@ Track::set_name (const string& str)
                return false;
        }
 
-       _diskstream->set_name (str);
+       if (_diskstream->playlist()->all_regions_empty ()) {
+               /* Only rename the diskstream (and therefore the playlist) if
+                  the playlist has never had a region added to it.  Otherwise
+                  people can get confused if, say, they have notes about a
+                  playlist with a given name and then it changes (see mantis
+                  #4759).
+               */
+               _diskstream->set_name (str);
+       }
 
        /* save state so that the statefile fully reflects any filename changes */
 
@@ -568,13 +593,13 @@ Track::hidden () const
 }
 
 int
-Track::can_internal_playback_seek (framepos_t p)
+Track::can_internal_playback_seek (framecnt_t p)
 {
        return _diskstream->can_internal_playback_seek (p);
 }
 
 int
-Track::internal_playback_seek (framepos_t p)
+Track::internal_playback_seek (framecnt_t p)
 {
        return _diskstream->internal_playback_seek (p);
 }
@@ -850,7 +875,7 @@ Track::maybe_declick (BufferSet& bufs, framecnt_t nframes, int declick)
 }
 
 framecnt_t
-Track::check_initial_delay (framecnt_t nframes, framecnt_t& transport_frame)
+Track::check_initial_delay (framecnt_t nframes, framepos_t& transport_frame)
 {
        if (_roll_delay > nframes) {