mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 15:54:57 +01:00
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
3 changed files with 54 additions and 91 deletions
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <list>
|
#include <set>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <glibmm/threads.h>
|
#include <glibmm/threads.h>
|
||||||
#include <sigc++/signal.h>
|
#include <sigc++/signal.h>
|
||||||
|
|
@ -41,7 +41,7 @@ class AutomationWatch : public sigc::trackable, public ARDOUR::SessionHandlePtr,
|
||||||
gint timer ();
|
gint timer ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::list<boost::shared_ptr<ARDOUR::AutomationControl> > AutomationWatches;
|
typedef std::set<boost::shared_ptr<ARDOUR::AutomationControl> > AutomationWatches;
|
||||||
|
|
||||||
AutomationWatch ();
|
AutomationWatch ();
|
||||||
~AutomationWatch();
|
~AutomationWatch();
|
||||||
|
|
@ -50,7 +50,7 @@ class AutomationWatch : public sigc::trackable, public ARDOUR::SessionHandlePtr,
|
||||||
Glib::Threads::Thread* _thread;
|
Glib::Threads::Thread* _thread;
|
||||||
bool _run_thread;
|
bool _run_thread;
|
||||||
AutomationWatches automation_watches;
|
AutomationWatches automation_watches;
|
||||||
Glib::Threads::Mutex automation_watch_lock;
|
Glib::Threads::Mutex automation_watch_lock;
|
||||||
PBD::ScopedConnection transport_connection;
|
PBD::ScopedConnection transport_connection;
|
||||||
|
|
||||||
void transport_state_change ();
|
void transport_state_change ();
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,6 @@
|
||||||
|
|
||||||
using namespace ARDOUR;
|
using namespace ARDOUR;
|
||||||
using namespace PBD;
|
using namespace PBD;
|
||||||
using std::cerr;
|
|
||||||
using std::endl;
|
|
||||||
|
|
||||||
AutomationWatch* AutomationWatch::_instance = 0;
|
AutomationWatch* AutomationWatch::_instance = 0;
|
||||||
|
|
||||||
|
|
@ -65,8 +63,8 @@ void
|
||||||
AutomationWatch::add_automation_watch (boost::shared_ptr<AutomationControl> ac)
|
AutomationWatch::add_automation_watch (boost::shared_ptr<AutomationControl> ac)
|
||||||
{
|
{
|
||||||
Glib::Threads::Mutex::Lock lm (automation_watch_lock);
|
Glib::Threads::Mutex::Lock lm (automation_watch_lock);
|
||||||
DEBUG_TRACE (DEBUG::Automation, string_compose ("now watching control %1 for automation\n", ac->name()));
|
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.push_back (ac);
|
automation_watches.insert (ac);
|
||||||
|
|
||||||
/* if an automation control is added here while the transport is
|
/* if an automation control is added here while the transport is
|
||||||
* rolling, make sure that it knows that there is a write pass going
|
* 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);
|
Glib::Threads::Mutex::Lock lm (automation_watch_lock);
|
||||||
DEBUG_TRACE (DEBUG::Automation, string_compose ("remove control %1 from automation watch\n", ac->name()));
|
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);
|
ac->list()->set_in_write_pass (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,7 +115,7 @@ AutomationWatch::timer ()
|
||||||
|
|
||||||
{
|
{
|
||||||
Glib::Threads::Mutex::Lock lm (automation_watch_lock);
|
Glib::Threads::Mutex::Lock lm (automation_watch_lock);
|
||||||
|
|
||||||
framepos_t time = _session->audible_frame ();
|
framepos_t time = _session->audible_frame ();
|
||||||
|
|
||||||
for (AutomationWatches::iterator aw = automation_watches.begin(); aw != automation_watches.end(); ++aw) {
|
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",
|
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())));
|
this, value, when, _in_write_pass, (most_recent_insert_iterator == _events.end())));
|
||||||
|
|
||||||
{
|
{
|
||||||
Glib::Threads::Mutex::Lock lm (_lock);
|
Glib::Threads::Mutex::Lock lm (_lock);
|
||||||
ControlEvent cp (when, 0.0f);
|
ControlEvent cp (when, 0.0f);
|
||||||
|
|
@ -416,7 +415,7 @@ ControlList::add (double when, double value)
|
||||||
* write pass.
|
* write pass.
|
||||||
*
|
*
|
||||||
* We need to add a new point at insert_position
|
* 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
|
/* the insert_iterator is not set, figure out where
|
||||||
|
|
@ -475,84 +474,31 @@ ControlList::add (double when, double value)
|
||||||
did_write_during_pass = true;
|
did_write_during_pass = true;
|
||||||
|
|
||||||
} else if (most_recent_insert_iterator == _events.end() || when > (*most_recent_insert_iterator)->when) {
|
} 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
|
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 %2 erase from existing iterator (@end ? %3)\n",
|
||||||
start of a write pass, and we have a bit of work to
|
this, (_in_write_pass ? "DO" : "DON'T"),
|
||||||
do figuring out where to add the new point, as well
|
(most_recent_insert_iterator == _events.end())));
|
||||||
as potentially erasing existing data between the
|
|
||||||
most recently added point and wherever this one
|
if (_in_write_pass) {
|
||||||
will end up.
|
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 need to discover insert iterator (@end ? %2)\n",
|
DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 erase existing @ %2\n", this, (*most_recent_insert_iterator)));
|
||||||
this, (most_recent_insert_iterator == _events.end())));
|
delete *most_recent_insert_iterator;
|
||||||
|
most_recent_insert_iterator = _events.erase (most_recent_insert_iterator);
|
||||||
/* this means that we either *know* we want to insert
|
continue;
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
++most_recent_insert_iterator;
|
} else if ((*most_recent_insert_iterator)->when >= when) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
++most_recent_insert_iterator;
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
}
|
||||||
|
} 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;
|
_events.back()->when = when;
|
||||||
done = true;
|
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) {
|
if (!done) {
|
||||||
_events.push_back (new ControlEvent (when, value));
|
_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) {
|
if (!_in_write_pass) {
|
||||||
|
|
@ -596,13 +544,28 @@ ControlList::add (double when, double value)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ((*most_recent_insert_iterator)->when == when) {
|
} 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
|
if ((*most_recent_insert_iterator)->value != value) {
|
||||||
* reset the value here.
|
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 {
|
} 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));
|
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;
|
most_recent_insert_iterator = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEBUG_TRACE (DEBUG::ControlList, string_compose ("final value of %1 moved to %2\n", value, when));
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -638,6 +602,7 @@ ControlList::add (double when, double value)
|
||||||
|
|
||||||
if (!done) {
|
if (!done) {
|
||||||
EventList::iterator x = _events.insert (most_recent_insert_iterator, new ControlEvent (when, value));
|
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) {
|
if (!_in_write_pass) {
|
||||||
most_recent_insert_iterator = x;
|
most_recent_insert_iterator = x;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue