#include "pbd/error.h"
#include "pbd/enumwriter.h"
+#include "pbd/stacktrace.h"
#include "midi++/names.h"
using namespace ARDOUR;
using namespace PBD;
-nframes_t Automatable::_automation_interval = 0;
+framecnt_t Automatable::_automation_interval = 0;
Automatable::Automatable(Session& session)
: _a_session(session)
* pass that type and it will be used for the untyped AutomationList found.
*/
int
-Automatable::set_automation_state (const XMLNode& node, Evoral::Parameter legacy_param)
+Automatable::set_automation_xml_state (const XMLNode& node, Evoral::Parameter legacy_param)
{
Glib::Mutex::Lock lm (control_lock());
if (param.type() == NullAutomation) {
warning << "Automation has null type" << endl;
continue;
- }
+ }
boost::shared_ptr<AutomationList> al (new AutomationList(**niter, param));
}
} else {
- error << "Expected AutomationList node, got '" << (*niter)->name() << endmsg;
+ error << "Expected AutomationList node, got '" << (*niter)->name() << "'" << endmsg;
}
}
}
XMLNode&
-Automatable::get_automation_state ()
+Automatable::get_automation_xml_state ()
{
Glib::Mutex::Lock lm (control_lock());
XMLNode* node = new XMLNode (X_("Automation"));
}
void
-Automatable::automation_snapshot (nframes_t now, bool force)
+Automatable::automation_snapshot (framepos_t now, bool force)
{
if (force || _last_automation_snapshot > now || (now - _last_automation_snapshot) > _automation_interval) {
for (Controls::iterator i = controls().begin(); i != controls().end(); ++i) {
boost::shared_ptr<AutomationControl> c
= boost::dynamic_pointer_cast<AutomationControl>(i->second);
- if (c->automation_write()) {
+ if (_a_session.transport_rolling() && c->automation_write()) {
c->list()->rt_add (now, i->second->user_double());
}
}
}
void
-Automatable::transport_stopped (sframes_t now)
+Automatable::transport_stopped (framepos_t now)
{
for (Controls::iterator li = controls().begin(); li != controls().end(); ++li) {
boost::shared_ptr<AutomationControl> c
= boost::dynamic_pointer_cast<AutomationControl>(li->second);
- boost::shared_ptr<AutomationList> l
+ if (c) {
+ boost::shared_ptr<AutomationList> l
= boost::dynamic_pointer_cast<AutomationList>(c->list());
-
- c->list()->reposition_for_rt_add (now);
-
- if (c->automation_state() != Off) {
- c->set_value(c->list()->eval(now));
- }
+
+ if (l) {
+ l->write_pass_finished (now);
+
+ if (l->automation_playback()) {
+ c->set_value(c->list()->eval(now));
+ }
+
+ if (l->automation_state() == Write) {
+ l->set_automation_state (Touch);
+ }
+ }
+ }
}
}
warning << "GainAutomation for non-Amp" << endl;
}
} else if (param.type() == PanAutomation) {
- Panner* me = dynamic_cast<Panner*>(this);
- if (me) {
- control = new Panner::PanControllable(me->session(), X_("panner"), *me, param);
+ Panner* panner = dynamic_cast<Panner*>(this);
+ if (panner) {
+ StreamPanner& sp (panner->streampanner (param.channel()));
+ control = new StreamPanner::PanControllable (_a_session, X_("direction"), &sp, param);
} else {
warning << "PanAutomation for non-Panner" << endl;
}