likely fixes for most remaining issues with data in automation/control lists, but more testing needed
git-svn-id: svn://localhost/ardour2/branches/3.0@13497 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
4a64b67d93
commit
bb9ab696b1
@ -17,7 +17,7 @@
|
||||
|
||||
*/
|
||||
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <glibmm/threads.h>
|
||||
#include <sigc++/signal.h>
|
||||
@ -41,7 +41,7 @@ class AutomationWatch : public sigc::trackable, public ARDOUR::SessionHandlePtr,
|
||||
gint timer ();
|
||||
|
||||
private:
|
||||
typedef std::list<boost::shared_ptr<ARDOUR::AutomationControl> > AutomationWatches;
|
||||
typedef std::set<boost::shared_ptr<ARDOUR::AutomationControl> > AutomationWatches;
|
||||
|
||||
AutomationWatch ();
|
||||
~AutomationWatch();
|
||||
@ -50,7 +50,7 @@ class AutomationWatch : public sigc::trackable, public ARDOUR::SessionHandlePtr,
|
||||
Glib::Threads::Thread* _thread;
|
||||
bool _run_thread;
|
||||
AutomationWatches automation_watches;
|
||||
Glib::Threads::Mutex automation_watch_lock;
|
||||
Glib::Threads::Mutex automation_watch_lock;
|
||||
PBD::ScopedConnection transport_connection;
|
||||
|
||||
void transport_state_change ();
|
||||
|
@ -28,8 +28,6 @@
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
AutomationWatch* AutomationWatch::_instance = 0;
|
||||
|
||||
@ -65,8 +63,8 @@ void
|
||||
AutomationWatch::add_automation_watch (boost::shared_ptr<AutomationControl> ac)
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (automation_watch_lock);
|
||||
DEBUG_TRACE (DEBUG::Automation, string_compose ("now watching control %1 for automation\n", ac->name()));
|
||||
automation_watches.push_back (ac);
|
||||
DEBUG_TRACE (DEBUG::Automation, string_compose ("now watching control %1 for automation, astate = %2\n", ac->name(), enum_2_string (ac->automation_state())));
|
||||
automation_watches.insert (ac);
|
||||
|
||||
/* if an automation control is added here while the transport is
|
||||
* rolling, make sure that it knows that there is a write pass going
|
||||
@ -104,7 +102,7 @@ AutomationWatch::remove_automation_watch (boost::shared_ptr<AutomationControl> a
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (automation_watch_lock);
|
||||
DEBUG_TRACE (DEBUG::Automation, string_compose ("remove control %1 from automation watch\n", ac->name()));
|
||||
automation_watches.remove (ac);
|
||||
automation_watches.erase (ac);
|
||||
ac->list()->set_in_write_pass (false);
|
||||
}
|
||||
|
||||
@ -117,7 +115,7 @@ AutomationWatch::timer ()
|
||||
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (automation_watch_lock);
|
||||
|
||||
|
||||
framepos_t time = _session->audible_frame ();
|
||||
|
||||
for (AutomationWatches::iterator aw = automation_watches.begin(); aw != automation_watches.end(); ++aw) {
|
||||
|
@ -390,7 +390,6 @@ ControlList::add (double when, double value)
|
||||
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 add %2 at %3 w/erase = %4 at end ? %5\n",
|
||||
this, value, when, _in_write_pass, (most_recent_insert_iterator == _events.end())));
|
||||
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (_lock);
|
||||
ControlEvent cp (when, 0.0f);
|
||||
@ -416,7 +415,7 @@ ControlList::add (double when, double value)
|
||||
* write pass.
|
||||
*
|
||||
* We need to add a new point at insert_position
|
||||
* corresponding the value there.
|
||||
* corresponding to the (existing, implicit) value there.
|
||||
*/
|
||||
|
||||
/* the insert_iterator is not set, figure out where
|
||||
@ -475,84 +474,31 @@ ControlList::add (double when, double value)
|
||||
did_write_during_pass = true;
|
||||
|
||||
} else if (most_recent_insert_iterator == _events.end() || when > (*most_recent_insert_iterator)->when) {
|
||||
|
||||
/* this is NOT the first point to be added after the
|
||||
start of a write pass, and we have a bit of work to
|
||||
do figuring out where to add the new point, as well
|
||||
as potentially erasing existing data between the
|
||||
most recently added point and wherever this one
|
||||
will end up.
|
||||
*/
|
||||
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 need to discover insert iterator (@end ? %2)\n",
|
||||
this, (most_recent_insert_iterator == _events.end())));
|
||||
|
||||
/* this means that we either *know* we want to insert
|
||||
* at the end, or that we don't know where to insert.
|
||||
*
|
||||
* so ... lets perform some quick checks before we
|
||||
* go doing binary search to figure out where to
|
||||
* insert.
|
||||
*/
|
||||
|
||||
if (_events.back()->when == when) {
|
||||
|
||||
/* we need to modify the final point, so
|
||||
make most_recent_insert_iterator point to it.
|
||||
*/
|
||||
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 modify final value\n", this));
|
||||
|
||||
most_recent_insert_iterator = _events.end();
|
||||
--most_recent_insert_iterator;
|
||||
|
||||
} else if (_events.back()->when < when) {
|
||||
|
||||
/* the new point is beyond the end of the
|
||||
* current list
|
||||
*/
|
||||
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 plan to append to list\n", this));
|
||||
|
||||
if (_in_write_pass) {
|
||||
/* remove the final point, because
|
||||
we're adding one beyond it.
|
||||
*/
|
||||
delete _events.back();
|
||||
_events.pop_back();
|
||||
}
|
||||
|
||||
/* leaving this here will force an append */
|
||||
|
||||
most_recent_insert_iterator = _events.end();
|
||||
|
||||
} else {
|
||||
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 erase %2 from existing iterator (@end ? %3\n",
|
||||
this, _in_write_pass,
|
||||
(most_recent_insert_iterator == _events.end())));
|
||||
|
||||
if (_in_write_pass) {
|
||||
while (most_recent_insert_iterator != _events.end()) {
|
||||
if ((*most_recent_insert_iterator)->when < when) {
|
||||
if (_in_write_pass) {
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 erase existing @ %2\n", this, (*most_recent_insert_iterator)));
|
||||
delete *most_recent_insert_iterator;
|
||||
most_recent_insert_iterator = _events.erase (most_recent_insert_iterator);
|
||||
continue;
|
||||
}
|
||||
} else if ((*most_recent_insert_iterator)->when >= when) {
|
||||
break;
|
||||
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 %2 erase from existing iterator (@end ? %3)\n",
|
||||
this, (_in_write_pass ? "DO" : "DON'T"),
|
||||
(most_recent_insert_iterator == _events.end())));
|
||||
|
||||
if (_in_write_pass) {
|
||||
while (most_recent_insert_iterator != _events.end()) {
|
||||
if ((*most_recent_insert_iterator)->when < when) {
|
||||
if (_in_write_pass) {
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 erase existing @ %2\n", this, (*most_recent_insert_iterator)));
|
||||
delete *most_recent_insert_iterator;
|
||||
most_recent_insert_iterator = _events.erase (most_recent_insert_iterator);
|
||||
continue;
|
||||
}
|
||||
++most_recent_insert_iterator;
|
||||
} else if ((*most_recent_insert_iterator)->when >= when) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
||||
/* not in a write pass: figure out the iterator we should insert in front of */
|
||||
|
||||
ControlEvent cp (when, 0.0f);
|
||||
most_recent_insert_iterator = lower_bound (_events.begin(), _events.end(), &cp, time_comparator);
|
||||
++most_recent_insert_iterator;
|
||||
}
|
||||
} else {
|
||||
|
||||
/* not in a write pass: figure out the iterator we should insert in front of */
|
||||
|
||||
ControlEvent cp (when, 0.0f);
|
||||
most_recent_insert_iterator = lower_bound (_events.begin(), _events.end(), &cp, time_comparator);
|
||||
}
|
||||
}
|
||||
|
||||
@ -581,6 +527,7 @@ ControlList::add (double when, double value)
|
||||
*/
|
||||
_events.back()->when = when;
|
||||
done = true;
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("final value of %1 moved to %2\n", value, when));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -588,6 +535,7 @@ ControlList::add (double when, double value)
|
||||
|
||||
if (!done) {
|
||||
_events.push_back (new ControlEvent (when, value));
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("\tactually appended, size now %1\n", _events.size()));
|
||||
}
|
||||
|
||||
if (!_in_write_pass) {
|
||||
@ -596,13 +544,28 @@ ControlList::add (double when, double value)
|
||||
}
|
||||
|
||||
} else if ((*most_recent_insert_iterator)->when == when) {
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 reset existing point to new value %2\n", this, value));
|
||||
|
||||
/* only one point allowed per time point, so just
|
||||
* reset the value here.
|
||||
*/
|
||||
if ((*most_recent_insert_iterator)->value != value) {
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 reset existing point to new value %2\n", this, value));
|
||||
|
||||
(*most_recent_insert_iterator)->value = value;
|
||||
/* only one point allowed per time point, so just
|
||||
* reset the value here.
|
||||
*/
|
||||
|
||||
(*most_recent_insert_iterator)->value = value;
|
||||
|
||||
/* if we modified the final value, then its as
|
||||
* if we inserted a new point as far as the
|
||||
* next addition, so make sure we know that.
|
||||
*/
|
||||
|
||||
if (_in_write_pass && _events.back()->when == when) {
|
||||
most_recent_insert_iterator = _events.end();
|
||||
}
|
||||
|
||||
} else {
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 same time %2, same value value %3\n", this, when, value));
|
||||
}
|
||||
|
||||
} else {
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert new point at %2 at iterator at %3\n", this, when, (*most_recent_insert_iterator)->when));
|
||||
@ -630,6 +593,7 @@ ControlList::add (double when, double value)
|
||||
most_recent_insert_iterator = b;
|
||||
}
|
||||
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("final value of %1 moved to %2\n", value, when));
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
@ -638,6 +602,7 @@ ControlList::add (double when, double value)
|
||||
|
||||
if (!done) {
|
||||
EventList::iterator x = _events.insert (most_recent_insert_iterator, new ControlEvent (when, value));
|
||||
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 inserted new value before MRI, size now %2\n", this, _events.size()));
|
||||
|
||||
if (!_in_write_pass) {
|
||||
most_recent_insert_iterator = x;
|
||||
|
Loading…
Reference in New Issue
Block a user