diff options
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/automatable.h | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/automation_control.h | 31 | ||||
-rw-r--r-- | libs/ardour/ardour/debug.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/rc_configuration_vars.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/route.h | 2 | ||||
-rw-r--r-- | libs/ardour/audio_track.cc | 2 | ||||
-rw-r--r-- | libs/ardour/automatable.cc | 60 | ||||
-rw-r--r-- | libs/ardour/automation_control.cc | 60 | ||||
-rw-r--r-- | libs/ardour/automation_list.cc | 27 | ||||
-rw-r--r-- | libs/ardour/buffer_manager.cc | 6 | ||||
-rw-r--r-- | libs/ardour/debug.cc | 1 | ||||
-rw-r--r-- | libs/ardour/midi_track.cc | 2 | ||||
-rw-r--r-- | libs/ardour/plugin_insert.cc | 2 | ||||
-rw-r--r-- | libs/ardour/route.cc | 34 | ||||
-rw-r--r-- | libs/ardour/session_transport.cc | 19 | ||||
-rw-r--r-- | libs/ardour/track.cc | 9 | ||||
-rw-r--r-- | libs/ardour/wscript | 1 |
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', |