summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2006-11-28 17:52:09 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2006-11-28 17:52:09 +0000
commitf3e5450492109bb4fab898ae824e30ede28bf7b5 (patch)
treec9cf6714aa8df9a07a395a03ba8c383d8fbe88c9 /libs/ardour
parent00afa40d458debc3fc53d25a6c077881678ea53e (diff)
major fixes to automation editing
git-svn-id: svn://localhost/ardour2/trunk@1161 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/automation_event.h6
-rw-r--r--libs/ardour/automation_event.cc76
2 files changed, 72 insertions, 10 deletions
diff --git a/libs/ardour/ardour/automation_event.h b/libs/ardour/ardour/automation_event.h
index e5c194e683..a2cfb23e61 100644
--- a/libs/ardour/ardour/automation_event.h
+++ b/libs/ardour/ardour/automation_event.h
@@ -82,7 +82,8 @@ class AutomationList : public PBD::StatefulDestructible
void clear ();
void x_scale (double factor);
bool extend_to (double);
-
+ void slide (iterator before, double distance);
+
void reposition_for_rt_add (double when);
void rt_add (double when, double value);
void add (double when, double value);
@@ -190,7 +191,7 @@ class AutomationList : public PBD::StatefulDestructible
AutomationEventList events;
mutable Glib::Mutex lock;
- bool _frozen;
+ int8_t _frozen;
bool changed_when_thawed;
bool _dirty;
@@ -209,6 +210,7 @@ class AutomationList : public PBD::StatefulDestructible
double min_yval;
double max_yval;
double default_value;
+ bool sort_pending;
iterator rt_insertion_point;
double rt_pos;
diff --git a/libs/ardour/automation_event.cc b/libs/ardour/automation_event.cc
index 0fa1f09bb1..6769cc25ec 100644
--- a/libs/ardour/automation_event.cc
+++ b/libs/ardour/automation_event.cc
@@ -36,6 +36,11 @@ using namespace PBD;
sigc::signal<void,AutomationList *> AutomationList::AutomationListCreated;
+static bool sort_events_by_time (ControlEvent* a, ControlEvent* b)
+{
+ return a->when < b->when;
+}
+
#if 0
static void dumpit (const AutomationList& al, string prefix = "")
{
@@ -49,7 +54,7 @@ static void dumpit (const AutomationList& al, string prefix = "")
AutomationList::AutomationList (double defval)
{
- _frozen = false;
+ _frozen = 0;
changed_when_thawed = false;
_state = Off;
_style = Absolute;
@@ -62,13 +67,14 @@ AutomationList::AutomationList (double defval)
rt_insertion_point = events.end();
lookup_cache.left = -1;
lookup_cache.range.first = events.end();
+ sort_pending = false;
AutomationListCreated(this);
}
AutomationList::AutomationList (const AutomationList& other)
{
- _frozen = false;
+ _frozen = 0;
changed_when_thawed = false;
_style = other._style;
min_yval = other.min_yval;
@@ -81,6 +87,7 @@ AutomationList::AutomationList (const AutomationList& other)
rt_insertion_point = events.end();
lookup_cache.left = -1;
lookup_cache.range.first = events.end();
+ sort_pending = false;
for (const_iterator i = other.events.begin(); i != other.events.end(); ++i) {
/* we have to use other point_factory() because
@@ -95,7 +102,7 @@ AutomationList::AutomationList (const AutomationList& other)
AutomationList::AutomationList (const AutomationList& other, double start, double end)
{
- _frozen = false;
+ _frozen = 0;
changed_when_thawed = false;
_style = other._style;
min_yval = other.min_yval;
@@ -108,6 +115,7 @@ AutomationList::AutomationList (const AutomationList& other, double start, doubl
rt_insertion_point = events.end();
lookup_cache.left = -1;
lookup_cache.range.first = events.end();
+ sort_pending = false;
/* now grab the relevant points, and shift them back if necessary */
@@ -128,7 +136,7 @@ AutomationList::AutomationList (const AutomationList& other, double start, doubl
AutomationList::AutomationList (const XMLNode& node)
{
- _frozen = false;
+ _frozen = 0;
changed_when_thawed = false;
_touching = false;
min_yval = FLT_MIN;
@@ -140,6 +148,7 @@ AutomationList::AutomationList (const XMLNode& node)
rt_insertion_point = events.end();
lookup_cache.left = -1;
lookup_cache.range.first = events.end();
+ sort_pending = false;
set_state (node);
@@ -517,6 +526,12 @@ AutomationList::move_range (iterator start, iterator end, double xdelta, double
++start;
}
+ if (!_frozen) {
+ events.sort (sort_events_by_time);
+ } else {
+ sort_pending = true;
+ }
+
mark_dirty ();
}
@@ -524,6 +539,25 @@ AutomationList::move_range (iterator start, iterator end, double xdelta, double
}
void
+AutomationList::slide (iterator before, double distance)
+{
+ {
+ Glib::Mutex::Lock lm (lock);
+
+ if (before == events.end()) {
+ return;
+ }
+
+ while (before != events.end()) {
+ (*before)->when += distance;
+ ++before;
+ }
+ }
+
+ maybe_signal_changed ();
+}
+
+void
AutomationList::modify (iterator iter, double when, double val)
{
/* note: we assume higher level logic is in place to avoid this
@@ -533,14 +567,23 @@ AutomationList::modify (iterator iter, double when, double val)
{
Glib::Mutex::Lock lm (lock);
+
(*iter)->when = when;
(*iter)->value = val;
+
if (isnan (val)) {
abort ();
}
+
+ if (!_frozen) {
+ events.sort (sort_events_by_time);
+ } else {
+ sort_pending = true;
+ }
+
mark_dirty ();
}
-
+
maybe_signal_changed ();
}
@@ -581,13 +624,30 @@ AutomationList::control_points_adjacent (double xval)
void
AutomationList::freeze ()
{
- _frozen = true;
+ _frozen++;
}
void
AutomationList::thaw ()
{
- _frozen = false;
+ if (_frozen == 0) {
+ fatal << string_compose (_("programming error: %1"), X_("AutomationList::thaw() called while not frozen")) << endmsg;
+ /*NOTREACHED*/
+ }
+
+ if (--_frozen > 0) {
+ return;
+ }
+
+ {
+ Glib::Mutex::Lock lm (lock);
+
+ if (sort_pending) {
+ events.sort (sort_events_by_time);
+ sort_pending = false;
+ }
+ }
+
if (changed_when_thawed) {
StateChanged(); /* EMIT SIGNAL */
}
@@ -1354,7 +1414,7 @@ AutomationList::set_state (const XMLNode& node)
deserialize_events (*(*niter));
}
}
-
+
return 0;
}