summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2012-07-13 21:05:45 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2012-07-13 21:05:45 +0000
commit0532e2063b73ec32d4dd108b58e90a0f20ae91b3 (patch)
treef9728e4b57f260fd5d468a9c3dd2b2dd2d97e7d7 /libs/ardour
parentb04cd7d7045dd40a1e3ae819ad3a2f9bb08a01f1 (diff)
dramatic overhaul of automation. too long to explain here. this work is not finished - write/touch passes do not correctly overwrite existing data because the semantics of ControlList::insert_iterator need clarification. more to follow
git-svn-id: svn://localhost/ardour2/branches/3.0@13038 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/automatable.h4
-rw-r--r--libs/ardour/ardour/automation_control.h31
-rw-r--r--libs/ardour/ardour/debug.h1
-rw-r--r--libs/ardour/ardour/rc_configuration_vars.h2
-rw-r--r--libs/ardour/ardour/route.h2
-rw-r--r--libs/ardour/audio_track.cc2
-rw-r--r--libs/ardour/automatable.cc60
-rw-r--r--libs/ardour/automation_control.cc60
-rw-r--r--libs/ardour/automation_list.cc27
-rw-r--r--libs/ardour/buffer_manager.cc6
-rw-r--r--libs/ardour/debug.cc1
-rw-r--r--libs/ardour/midi_track.cc2
-rw-r--r--libs/ardour/plugin_insert.cc2
-rw-r--r--libs/ardour/route.cc34
-rw-r--r--libs/ardour/session_transport.cc19
-rw-r--r--libs/ardour/track.cc9
-rw-r--r--libs/ardour/wscript1
17 files changed, 145 insertions, 118 deletions
diff --git a/libs/ardour/ardour/automatable.h b/libs/ardour/ardour/automatable.h
index dc86c0cddd..6e0f7a97b5 100644
--- a/libs/ardour/ardour/automatable.h
+++ b/libs/ardour/ardour/automatable.h
@@ -45,7 +45,7 @@ public:
Automatable(Session&);
Automatable (const Automatable& other);
- virtual ~Automatable() {}
+ virtual ~Automatable();
boost::shared_ptr<Evoral::Control>
control_factory(const Evoral::Parameter& id);
@@ -59,7 +59,7 @@ public:
virtual void add_control(boost::shared_ptr<Evoral::Control>);
void clear_controls ();
- virtual void automation_snapshot (framepos_t now, bool force);
+ virtual void transport_located (framepos_t now);
virtual void transport_stopped (framepos_t now);
virtual std::string describe_parameter(Evoral::Parameter param);
diff --git a/libs/ardour/ardour/automation_control.h b/libs/ardour/ardour/automation_control.h
index 2c15a1b1b0..10194b3f9b 100644
--- a/libs/ardour/ardour/automation_control.h
+++ b/libs/ardour/ardour/automation_control.h
@@ -22,6 +22,8 @@
#define __ardour_automation_control_h__
#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
#include "pbd/controllable.h"
#include "evoral/Control.hpp"
#include "ardour/automation_list.h"
@@ -34,7 +36,7 @@ class Automatable;
/** A PBD::Controllable with associated automation data (AutomationList)
*/
-class AutomationControl : public PBD::Controllable, public Evoral::Control
+class AutomationControl : public PBD::Controllable, public Evoral::Control, public boost::enable_shared_from_this<AutomationControl>
{
public:
AutomationControl(ARDOUR::Session&,
@@ -42,37 +44,34 @@ public:
boost::shared_ptr<ARDOUR::AutomationList> l=boost::shared_ptr<ARDOUR::AutomationList>(),
const std::string& name="");
+ ~AutomationControl ();
+
boost::shared_ptr<AutomationList> alist() const {
return boost::dynamic_pointer_cast<AutomationList>(_list);
}
- void set_list(boost::shared_ptr<Evoral::ControlList>);
+ void set_list (boost::shared_ptr<Evoral::ControlList>);
inline bool automation_playback() const {
- return ((ARDOUR::AutomationList*)_list.get())->automation_playback();
+ return alist()->automation_playback();
}
inline bool automation_write() const {
- return ((ARDOUR::AutomationList*)_list.get())->automation_write();
+ return alist()->automation_write();
}
inline AutoState automation_state() const {
- return ((ARDOUR::AutomationList*)_list.get())->automation_state();
+ return alist()->automation_state();
}
- inline void set_automation_state(AutoState as) {
- return ((ARDOUR::AutomationList*)_list.get())->set_automation_state(as);
+ inline AutoStyle automation_style() const {
+ return alist()->automation_style();
}
- inline void start_touch(double when) {
- set_touching (true);
- return ((ARDOUR::AutomationList*)_list.get())->start_touch(when);
- }
-
- inline void stop_touch(bool mark, double when) {
- set_touching (false);
- return ((ARDOUR::AutomationList*)_list.get())->stop_touch(mark, when);
- }
+ void set_automation_state(AutoState as);
+ void set_automation_style(AutoStyle as);
+ void start_touch (double when);
+ void stop_touch (bool mark, double when);
void set_value (double);
double get_value () const;
diff --git a/libs/ardour/ardour/debug.h b/libs/ardour/ardour/debug.h
index 5c72c9236f..334aac53e6 100644
--- a/libs/ardour/ardour/debug.h
+++ b/libs/ardour/ardour/debug.h
@@ -60,6 +60,7 @@ namespace PBD {
extern uint64_t TempoMath;
extern uint64_t TempoMap;
extern uint64_t OrderKeys;
+ extern uint64_t Automation;
}
}
diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h
index 37599b0ac6..09b0c55a74 100644
--- a/libs/ardour/ardour/rc_configuration_vars.h
+++ b/libs/ardour/ardour/rc_configuration_vars.h
@@ -152,7 +152,7 @@ CONFIG_VARIABLE (int32_t, history_depth, "history-depth", 20)
CONFIG_VARIABLE (bool, use_overlap_equivalency, "use-overlap-equivalency", false)
CONFIG_VARIABLE (bool, periodic_safety_backups, "periodic-safety-backups", true)
CONFIG_VARIABLE (uint32_t, periodic_safety_backup_interval, "periodic-safety-backup-interval", 120)
-CONFIG_VARIABLE (float, automation_interval, "automation-interval", 50)
+CONFIG_VARIABLE (float, automation_interval, "automation-interval", 500)
CONFIG_VARIABLE (bool, sync_all_route_ordering, "sync-all-route-ordering", true)
CONFIG_VARIABLE (bool, only_copy_imported_files, "only-copy-imported-files", false)
CONFIG_VARIABLE (bool, keep_tearoffs, "keep-tearoffs", false)
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index f6c737d766..22ecb19123 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -131,6 +131,7 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
virtual void nonrealtime_handle_transport_stopped (bool abort, bool did_locate, bool flush_processors);
virtual void realtime_handle_transport_stopped () {}
virtual void realtime_locate () {}
+ virtual void non_realtime_locate (framepos_t);
virtual void set_pending_declick (int);
/* end of vfunc-based API */
@@ -409,7 +410,6 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
boost::shared_ptr<Processor> the_instrument() const;
InstrumentInfo& instrument_info() { return _instrument_info; }
- void automation_snapshot (framepos_t now, bool force=false);
void protect_automation ();
enum {
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index 6161147f44..4079cdb481 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -321,8 +321,6 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram
framepos_t transport_frame;
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
- automation_snapshot (start_frame, false);
-
if (n_outputs().n_total() == 0 && _processors.empty()) {
return 0;
}
diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc
index d0a605bcd9..608ae745de 100644
--- a/libs/ardour/automatable.cc
+++ b/libs/ardour/automatable.cc
@@ -47,14 +47,12 @@ const string Automatable::xml_node_name = X_("Automation");
Automatable::Automatable(Session& session)
: _a_session(session)
- , _last_automation_snapshot(0)
{
}
Automatable::Automatable (const Automatable& other)
: ControlSet (other)
, _a_session (other._a_session)
- , _last_automation_snapshot (0)
{
Glib::Mutex::Lock lm (other._control_lock);
@@ -63,6 +61,18 @@ Automatable::Automatable (const Automatable& other)
add_control (ac);
}
}
+
+Automatable::~Automatable ()
+{
+ {
+ Glib::Mutex::Lock lm (_control_lock);
+
+ for (Controls::const_iterator li = _controls.begin(); li != _controls.end(); ++li) {
+ boost::dynamic_pointer_cast<AutomationControl>(li->second)->drop_references ();
+ }
+ }
+}
+
int
Automatable::old_set_automation_state (const XMLNode& node)
{
@@ -74,8 +84,6 @@ Automatable::old_set_automation_state (const XMLNode& node)
warning << _("Automation node has no path property") << endmsg;
}
- _last_automation_snapshot = 0;
-
return 0;
}
@@ -102,8 +110,6 @@ Automatable::load_automation (const string& path)
set<Evoral::Parameter> tosave;
controls().clear ();
- _last_automation_snapshot = 0;
-
while (in) {
double when;
double value;
@@ -228,8 +234,6 @@ Automatable::set_automation_xml_state (const XMLNode& node, Evoral::Parameter le
}
}
- _last_automation_snapshot = 0;
-
return 0;
}
@@ -258,11 +262,10 @@ Automatable::set_parameter_automation_state (Evoral::Parameter param, AutoState
{
Glib::Mutex::Lock lm (control_lock());
- boost::shared_ptr<Evoral::Control> c = control (param, true);
- boost::shared_ptr<AutomationList> l = boost::dynamic_pointer_cast<AutomationList>(c->list());
+ boost::shared_ptr<AutomationControl> c = automation_control (param, true);
- if (s != l->automation_state()) {
- l->set_automation_state (s);
+ if (c && (s != c->automation_state())) {
+ c->set_automation_state (s);
_a_session.set_dirty ();
}
}
@@ -272,11 +275,10 @@ Automatable::get_parameter_automation_state (Evoral::Parameter param)
{
AutoState result = Off;
- boost::shared_ptr<Evoral::Control> c = control(param);
- boost::shared_ptr<AutomationList> l = boost::dynamic_pointer_cast<AutomationList>(c->list());
-
+ boost::shared_ptr<AutomationControl> c = automation_control(param);
+
if (c) {
- result = l->automation_state();
+ result = c->automation_state();
}
return result;
@@ -287,11 +289,10 @@ Automatable::set_parameter_automation_style (Evoral::Parameter param, AutoStyle
{
Glib::Mutex::Lock lm (control_lock());
- boost::shared_ptr<Evoral::Control> c = control(param, true);
- boost::shared_ptr<AutomationList> l = boost::dynamic_pointer_cast<AutomationList>(c->list());
+ boost::shared_ptr<AutomationControl> c = automation_control(param, true);
- if (s != l->automation_style()) {
- l->set_automation_style (s);
+ if (c && (s != c->automation_style())) {
+ c->set_automation_style (s);
_a_session.set_dirty ();
}
}
@@ -336,19 +337,20 @@ Automatable::protect_automation ()
}
void
-Automatable::automation_snapshot (framepos_t now, bool force)
+Automatable::transport_located (framepos_t now)
{
- if (force || _last_automation_snapshot > now || (now - _last_automation_snapshot) > _automation_interval) {
+ for (Controls::iterator li = controls().begin(); li != controls().end(); ++li) {
+
+ boost::shared_ptr<AutomationControl> c
+ = boost::dynamic_pointer_cast<AutomationControl>(li->second);
+ if (c) {
+ boost::shared_ptr<AutomationList> l
+ = boost::dynamic_pointer_cast<AutomationList>(c->list());
- for (Controls::iterator i = controls().begin(); i != controls().end(); ++i) {
- boost::shared_ptr<AutomationControl> c
- = boost::dynamic_pointer_cast<AutomationControl>(i->second);
- if (_a_session.transport_rolling() && c->automation_write()) {
- c->list()->rt_add (now, i->second->user_double());
+ if (l) {
+ l->start_write_pass (now);
}
}
-
- _last_automation_snapshot = now;
}
}
diff --git a/libs/ardour/automation_control.cc b/libs/ardour/automation_control.cc
index 05463dcdd0..1fde567e28 100644
--- a/libs/ardour/automation_control.cc
+++ b/libs/ardour/automation_control.cc
@@ -21,6 +21,7 @@
#include <iostream>
#include "ardour/automation_control.h"
+#include "ardour/automation_watch.h"
#include "ardour/event_type_map.h"
#include "ardour/session.h"
@@ -39,6 +40,10 @@ AutomationControl::AutomationControl(
{
}
+AutomationControl::~AutomationControl ()
+{
+}
+
/** Get the current effective `user' value based on automation state */
double
AutomationControl::get_value() const
@@ -52,17 +57,18 @@ AutomationControl::get_value() const
* @param value `user' value
*/
void
-AutomationControl::set_value(double value)
+AutomationControl::set_value (double value)
{
- bool to_list = _list && _session.transport_stopped()
- && ((AutomationList*)_list.get())->automation_write();
+ bool to_list = _list && ((AutomationList*)_list.get())->automation_write();
if (to_list && parameter().toggled()) {
// store the previous value just before this so any
// interpolation works right
- _list->add (get_double(), _session.transport_frame()-1);
+ bool erase_since_last = _session.transport_rolling();
+
+ _list->add (get_double(), _session.transport_frame()-1, erase_since_last);
}
Control::set_double (value, to_list, _session.transport_frame());
@@ -72,9 +78,51 @@ AutomationControl::set_value(double value)
void
-AutomationControl::set_list(boost::shared_ptr<Evoral::ControlList> list)
+AutomationControl::set_list (boost::shared_ptr<Evoral::ControlList> list)
{
- Control::set_list(list);
+ Control::set_list (list);
Changed(); /* EMIT SIGNAL */
}
+void
+AutomationControl::set_automation_state (AutoState as)
+{
+ if (as != alist()->automation_state()) {
+
+ cerr << name() << " setting automation state to " << enum_2_string (as) << endl;
+
+ if (as == Write) {
+ AutomationWatch::instance().add_automation_watch (shared_from_this());
+ } else if (as == Touch) {
+ if (!touching()) {
+ AutomationWatch::instance().remove_automation_watch (shared_from_this());
+ }
+ } else {
+ AutomationWatch::instance().remove_automation_watch (shared_from_this());
+ }
+
+ alist()->set_automation_state (as);
+ }
+}
+
+void
+AutomationControl::set_automation_style (AutoStyle as)
+{
+ alist()->set_automation_style (as);
+}
+
+void
+AutomationControl::start_touch(double when)
+{
+ set_touching (true);
+ AutomationWatch::instance().add_automation_watch (shared_from_this());
+ alist()->start_touch(when);
+}
+
+void
+AutomationControl::stop_touch(bool mark, double when)
+{
+ set_touching (false);
+ AutomationWatch::instance().remove_automation_watch (shared_from_this());
+ alist()->stop_touch (mark, when);
+}
diff --git a/libs/ardour/automation_list.cc b/libs/ardour/automation_list.cc
index 26ca7b097a..39e7bacc46 100644
--- a/libs/ardour/automation_list.cc
+++ b/libs/ardour/automation_list.cc
@@ -180,11 +180,6 @@ AutomationList::set_automation_state (AutoState s)
{
if (s != _state) {
_state = s;
-
- if (_state == Write) {
- Glib::Mutex::Lock lm (ControlList::_lock);
- nascent.push_back (new NascentInfo ());
- }
automation_state_changed (s); /* EMIT SIGNAL */
}
}
@@ -202,8 +197,7 @@ void
AutomationList::start_touch (double when)
{
if (_state == Touch) {
- Glib::Mutex::Lock lm (ControlList::_lock);
- nascent.push_back (new NascentInfo (when));
+ start_write_pass (when);
}
g_atomic_int_set (&_touching, 1);
@@ -223,22 +217,11 @@ AutomationList::stop_touch (bool mark, double when)
if (_state == Touch) {
- assert (!nascent.empty ());
-
- Glib::Mutex::Lock lm (ControlList::_lock);
-
if (mark) {
-
- nascent.back()->end_time = when;
-
- } else {
-
- /* nascent info created in start touch but never used. just get rid of it.
- */
-
- NascentInfo* ninfo = nascent.back ();
- nascent.erase (nascent.begin());
- delete ninfo;
+
+ /* XXX need to mark the last added point with the
+ * current time
+ */
}
}
}
diff --git a/libs/ardour/buffer_manager.cc b/libs/ardour/buffer_manager.cc
index e3bc2cb97c..71ff4946f3 100644
--- a/libs/ardour/buffer_manager.cc
+++ b/libs/ardour/buffer_manager.cc
@@ -48,7 +48,7 @@ BufferManager::init (uint32_t size)
thread_buffers->write (&ts, 1);
thread_buffers_list->push_back (ts);
}
- cerr << "Initialized thread buffers, readable count now " << thread_buffers->read_space() << endl;
+ // cerr << "Initialized thread buffers, readable count now " << thread_buffers->read_space() << endl;
}
@@ -59,7 +59,7 @@ BufferManager::get_thread_buffers ()
ThreadBuffers* tbp;
if (thread_buffers->read (&tbp, 1) == 1) {
- cerr << "Got thread buffers, readable count now " << thread_buffers->read_space() << endl;
+ // cerr << "Got thread buffers, readable count now " << thread_buffers->read_space() << endl;
return tbp;
}
@@ -71,7 +71,7 @@ BufferManager::put_thread_buffers (ThreadBuffers* tbp)
{
Glib::Mutex::Lock em (rb_mutex);
thread_buffers->write (&tbp, 1);
- cerr << "Put back thread buffers, readable count now " << thread_buffers->read_space() << endl;
+ // cerr << "Put back thread buffers, readable count now " << thread_buffers->read_space() << endl;
}
void
diff --git a/libs/ardour/debug.cc b/libs/ardour/debug.cc
index db0f409d11..0d0948d576 100644
--- a/libs/ardour/debug.cc
+++ b/libs/ardour/debug.cc
@@ -57,5 +57,6 @@ uint64_t PBD::DEBUG::Layering = PBD::new_debug_bit ("layering");
uint64_t PBD::DEBUG::TempoMath = PBD::new_debug_bit ("tempomath");
uint64_t PBD::DEBUG::TempoMap = PBD::new_debug_bit ("tempomap");
uint64_t PBD::DEBUG::OrderKeys = PBD::new_debug_bit ("orderkeys");
+uint64_t PBD::DEBUG::Automation = PBD::new_debug_bit ("automation");
diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc
index 1d352d622b..800e7949d5 100644
--- a/libs/ardour/midi_track.cc
+++ b/libs/ardour/midi_track.cc
@@ -283,8 +283,6 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame
boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
- automation_snapshot (start_frame);
-
if (n_outputs().n_total() == 0 && _processors.empty()) {
return 0;
}
diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc
index 6e7cfe373f..f390e190f5 100644
--- a/libs/ardour/plugin_insert.cc
+++ b/libs/ardour/plugin_insert.cc
@@ -267,7 +267,7 @@ PluginInsert::parameter_changed (uint32_t which, float val)
boost::shared_ptr<AutomationControl> ac = automation_control (Evoral::Parameter (PluginAutomation, 0, which));
if (ac) {
- ac->set_double (val);
+ ac->set_value (val);
Plugins::iterator i = _plugins.begin();
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 1a6bff5096..80b738e003 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -2930,10 +2930,6 @@ Route::nonrealtime_handle_transport_stopped (bool /*abort_ignored*/, bool did_lo
{
Glib::RWLock::ReaderLock lm (_processor_lock);
- if (!did_locate) {
- automation_snapshot (now, true);
- }
-
Automatable::transport_stopped (now);
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
@@ -3061,8 +3057,6 @@ Route::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, in
return 0;
}
- automation_snapshot (_session.transport_frame(), false);
-
if (n_outputs().n_total() == 0) {
return 0;
}
@@ -3274,18 +3268,6 @@ Route::set_latency_compensation (framecnt_t longest_session_latency)
}
}
-void
-Route::automation_snapshot (framepos_t now, bool force)
-{
- if (_pannable) {
- _pannable->automation_snapshot (now, force);
- }
-
- for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
- (*i)->automation_snapshot (now, force);
- }
-}
-
Route::SoloControllable::SoloControllable (std::string name, boost::shared_ptr<Route> r)
: AutomationControl (r->session(), Evoral::Parameter (SoloAutomation),
boost::shared_ptr<AutomationList>(), name)
@@ -4174,3 +4156,19 @@ Route::the_instrument () const
}
return boost::shared_ptr<Processor>();
}
+
+void
+Route::non_realtime_locate (framepos_t pos)
+{
+ if (_pannable) {
+ _pannable->transport_located (pos);
+ }
+
+ {
+ Glib::RWLock::WriterLock lm (_processor_lock);
+
+ for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
+ (*i)->transport_located (pos);
+ }
+ }
+}
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index a878b9fabc..b5fb2a790f 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -299,8 +299,8 @@ Session::butler_transport_work ()
if (tr) {
tr->adjust_playback_buffering ();
/* and refill those buffers ... */
- tr->non_realtime_locate (_transport_frame);
}
+ (*i)->non_realtime_locate (_transport_frame);
}
}
@@ -344,10 +344,8 @@ Session::butler_transport_work ()
if (!(ptw & PostTransportLocate)) {
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
- boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
- if (tr && !tr->hidden()) {
- tr->non_realtime_locate (_transport_frame);
- }
+ (*i)->non_realtime_locate (_transport_frame);
+
if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
/* new request, stop seeking, and start again */
g_atomic_int_dec_and_test (&_butler->should_do_transport_work);
@@ -420,10 +418,7 @@ Session::non_realtime_locate ()
{
boost::shared_ptr<RouteList> rl = routes.reader();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
- boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
- if (tr) {
- tr->non_realtime_locate (_transport_frame);
- }
+ (*i)->non_realtime_locate (_transport_frame);
}
/* XXX: it would be nice to generate the new clicks here (in the non-RT thread)
@@ -601,10 +596,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
DEBUG_TRACE (DEBUG::Transport, X_("Butler PTW: locate\n"));
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
DEBUG_TRACE (DEBUG::Transport, string_compose ("Butler PTW: locate on %1\n", (*i)->name()));
- boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
- if (tr && !tr->hidden()) {
- tr->non_realtime_locate (_transport_frame);
- }
+ (*i)->non_realtime_locate (_transport_frame);
if (on_entry != g_atomic_int_get (&_butler->should_do_transport_work)) {
finished = false;
@@ -1236,7 +1228,6 @@ Session::start_transport ()
if (tr) {
tr->realtime_set_speed (tr->speed(), true);
}
- (*i)->automation_snapshot (_transport_frame, true);
}
if (!_engine.freewheeling()) {
diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc
index 0dc0a9f676..452a0843e2 100644
--- a/libs/ardour/track.cc
+++ b/libs/ardour/track.cc
@@ -620,7 +620,14 @@ Track::non_realtime_input_change ()
void
Track::non_realtime_locate (framepos_t p)
{
- _diskstream->non_realtime_locate (p);
+ Route::non_realtime_locate (p);
+
+ if (!hidden()) {
+ /* don't waste i/o cycles and butler calls
+ for hidden (secret) tracks
+ */
+ _diskstream->non_realtime_locate (p);
+ }
}
void
diff --git a/libs/ardour/wscript b/libs/ardour/wscript
index 04f67f7eb1..672dae6abd 100644
--- a/libs/ardour/wscript
+++ b/libs/ardour/wscript
@@ -55,6 +55,7 @@ libardour_sources = [
'automation.cc',
'automation_control.cc',
'automation_list.cc',
+ 'automation_watch.cc',
'beats_frames_converter.cc',
'broadcast_info.cc',
'buffer.cc',