static void dumpit (const AutomationList& al, string prefix = "")
{
cerr << prefix << &al << endl;
- for (AutomationList::const_iterator i = al.const_begin(); i != al.const_end(); ++i) {
+ for (AutomationList::const_iterator i = al.begin(); i != al.end(); ++i) {
cerr << prefix << '\t' << (*i)->when << ',' << (*i)->value << endl;
}
cerr << "\n";
}
#endif
-
AutomationList::AutomationList (Evoral::Parameter id)
: ControlList(id)
{
_state = Off;
_style = Absolute;
- _touching = false;
+ g_atomic_int_set (&_touching, 0);
create_curve_if_necessary();
{
_style = other._style;
_state = other._state;
- _touching = other._touching;
+ g_atomic_int_set (&_touching, other.touching());
create_curve_if_necessary();
{
_style = other._style;
_state = other._state;
- _touching = other._touching;
+ g_atomic_int_set (&_touching, other.touching());
create_curve_if_necessary();
AutomationList::AutomationList (const XMLNode& node, Evoral::Parameter id)
: ControlList(id)
{
- _touching = false;
+ g_atomic_int_set (&_touching, 0);
_state = Off;
_style = Absolute;
{
switch (_parameter.type()) {
case GainAutomation:
- case PanAutomation:
+ case PanAzimuthAutomation:
+ case PanElevationAutomation:
+ case PanWidthAutomation:
case FadeInAutomation:
case FadeOutAutomation:
case EnvelopeAutomation:
_min_yval = other._min_yval;
_max_yval = other._max_yval;
- _max_xval = other._max_xval;
_default_value = other._default_value;
mark_dirty ();
}
void
-AutomationList::start_touch ()
+AutomationList::start_touch (double when)
{
- _touching = true;
- _new_value = true;
+ if (_state == Touch) {
+ start_write_pass (when);
+ }
+
+ g_atomic_int_set (&_touching, 1);
}
void
-AutomationList::stop_touch ()
+AutomationList::stop_touch (bool mark, double)
{
- _touching = false;
- _new_value = false;
+ if (g_atomic_int_get (&_touching) == 0) {
+ /* this touch has already been stopped (probably by Automatable::transport_stopped),
+ so we've nothing to do.
+ */
+ return;
+ }
+
+ g_atomic_int_set (&_touching, 0);
+
+ if (_state == Touch) {
+
+ if (mark) {
+
+ /* XXX need to mark the last added point with the
+ * current time
+ */
+ }
+ }
}
void
root->add_property ("automation-id", EventTypeMap::instance().to_symbol(_parameter));
- root->add_property ("id", _id.to_s());
+ root->add_property ("id", id().to_s());
snprintf (buf, sizeof (buf), "%.12g", _default_value);
root->add_property ("default", buf);
root->add_property ("min-yval", buf);
snprintf (buf, sizeof (buf), "%.12g", _max_yval);
root->add_property ("max-yval", buf);
- snprintf (buf, sizeof (buf), "%.12g", _max_xval);
- root->add_property ("max-xval", buf);
root->add_property ("interpolation-style", enum_2_string (_interpolation));
if (full) {
- root->add_property ("state", auto_state_to_string (_state));
+ /* never serialize state with Write enabled - too dangerous
+ for the user's data
+ */
+ if (_state != Write) {
+ root->add_property ("state", auto_state_to_string (_state));
+ } else {
+ root->add_property ("state", auto_state_to_string (Off));
+ }
} else {
/* never save anything but Off for automation state to a template */
root->add_property ("state", auto_state_to_string (Off));
fast_simple_add (x, y);
}
+ thin ();
+
if (!ok) {
clear ();
error << _("automation list: cannot load coordinates from XML, all points ignored") << endmsg;
} else {
mark_dirty ();
- reposition_for_rt_add (0);
maybe_signal_changed ();
}
thaw ();
-
+
return 0;
}
int
AutomationList::set_state (const XMLNode& node, int version)
{
+ LocaleGuard lg (X_("POSIX"));
XMLNodeList nlist = node.children();
XMLNode* nsos;
XMLNodeIterator niter;
const XMLNodeList& elist = node.children();
XMLNodeConstIterator i;
XMLProperty* prop;
- nframes_t x;
+ pframes_t x;
double y;
ControlList::freeze ();
fast_simple_add (x, y);
}
+ thin ();
+
thaw ();
return 0;
return -1;
}
- if ((prop = node.property ("id")) != 0) {
- _id = prop->value ();
+ if (set_id (node)) {
/* update session AL list */
AutomationListCreated(this);
}
if ((prop = node.property (X_("automation-id"))) != 0){
_parameter = EventTypeMap::instance().new_parameter(prop->value());
} else {
- warning << "Legacy session: automation list has no automation-id property.";
+ warning << "Legacy session: automation list has no automation-id property." << endmsg;
}
if ((prop = node.property (X_("interpolation-style"))) != 0) {
if ((prop = node.property (X_("state"))) != 0) {
_state = string_to_auto_state (prop->value());
+ if (_state == Write) {
+ _state = Off;
+ }
+ automation_state_changed(_state);
} else {
_state = Off;
}
- if ((prop = node.property (X_("min_yval"))) != 0) {
+ if ((prop = node.property (X_("min-yval"))) != 0) {
_min_yval = atof (prop->value ().c_str());
} else {
_min_yval = FLT_MIN;
}
- if ((prop = node.property (X_("max_yval"))) != 0) {
+ if ((prop = node.property (X_("max-yval"))) != 0) {
_max_yval = atof (prop->value ().c_str());
} else {
_max_yval = FLT_MAX;
}
- if ((prop = node.property (X_("max_xval"))) != 0) {
- _max_xval = atof (prop->value ().c_str());
- } else {
- _max_xval = 0; // means "no limit ;
- }
-
bool have_events = false;
-
+
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((*niter)->name() == X_("events")) {
deserialize_events (*(*niter));
freeze ();
clear ();
mark_dirty ();
- reposition_for_rt_add (0);
maybe_signal_changed ();
thaw ();
}
return 0;
}
+bool
+AutomationList::operator!= (AutomationList const & other) const
+{
+ return (
+ static_cast<ControlList const &> (*this) != static_cast<ControlList const &> (other) ||
+ _state != other._state ||
+ _style != other._style ||
+ _touching != other._touching
+ );
+}
+
+PBD::PropertyBase *
+AutomationListProperty::clone () const
+{
+ return new AutomationListProperty (
+ this->property_id(),
+ boost::shared_ptr<AutomationList> (new AutomationList (*this->_old.get())),
+ boost::shared_ptr<AutomationList> (new AutomationList (*this->_current.get()))
+ );
+}
+