Fix controller iteration / linear interpolation.
Add unit test for controller iteration / linear interpolation. git-svn-id: svn://localhost/ardour2/branches/3.0@5886 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
653a487bbd
commit
82a0c02af1
@ -75,7 +75,7 @@ public:
|
||||
* f(x, y) and f(x, z) hold => !f(x, z)
|
||||
*
|
||||
* That implies one of the following:
|
||||
* <ol>
|
||||
* <ol>
|
||||
* <li> x == z which contradicts the assumption f(x, y) and f(y, x)
|
||||
* because of antisymmetry.
|
||||
* </li>
|
||||
|
@ -97,7 +97,7 @@ Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>& seq, Time t
|
||||
for (Controls::const_iterator i = seq._controls.begin(); i != seq._controls.end(); ++i) {
|
||||
DUMP(format("Iterator: control: %1%\n") % seq._type_map.to_symbol(i->first));
|
||||
double x, y;
|
||||
bool ret = i->second->list()->rt_safe_earliest_event_unlocked(t, DBL_MAX, x, y);
|
||||
bool ret = i->second->list()->rt_safe_earliest_event_unlocked(t, DBL_MAX, x, y, true);
|
||||
if (!ret) {
|
||||
DUMP(format("Iterator: CC %1% (size %2%) has no events past %3%\n")
|
||||
% i->first.id() % i->second->list()->size() % t);
|
||||
@ -128,6 +128,7 @@ Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>& seq, Time t
|
||||
|
||||
if (found) {
|
||||
_control_iter = _control_iters.begin() + earliest_control_index;
|
||||
assert(_control_iter != _control_iters.end());
|
||||
} else {
|
||||
_control_iter = _control_iters.end();
|
||||
}
|
||||
@ -140,14 +141,15 @@ Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>& seq, Time t
|
||||
earliest_t = (*_note_iter)->time();
|
||||
}
|
||||
|
||||
if (_sysex_iter != seq.sysexes().end() && (*_sysex_iter)->time() < earliest_t) {
|
||||
if (_sysex_iter != seq.sysexes().end()
|
||||
&& ((*_sysex_iter)->time() < earliest_t || _type == NIL)) {
|
||||
_type = SYSEX;
|
||||
earliest_t = (*_sysex_iter)->time();
|
||||
}
|
||||
|
||||
if (_control_iter != _control_iters.end()
|
||||
&& earliest_control.list && earliest_control.x >= t
|
||||
&& earliest_control.x < earliest_t) {
|
||||
&& (earliest_control.x < earliest_t || _type == NIL)) {
|
||||
_type = CONTROL;
|
||||
earliest_t = earliest_control.x;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "SequenceTest.hpp"
|
||||
#include "evoral/MIDIParameters.hpp"
|
||||
#include <cassert>
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(SequenceTest);
|
||||
@ -62,7 +63,6 @@ SequenceTest::preserveEventOrderingTest ()
|
||||
CPPUNIT_ASSERT_EQUAL(size_t(12), test_notes.size());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SequenceTest::iteratorSeekTest ()
|
||||
{
|
||||
@ -89,3 +89,68 @@ SequenceTest::iteratorSeekTest ()
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(num_notes, size_t(6));
|
||||
}
|
||||
|
||||
void
|
||||
SequenceTest::controlInterpolationTest ()
|
||||
{
|
||||
seq->clear();
|
||||
|
||||
for (Notes::const_iterator i = test_notes.begin(); i != test_notes.end(); ++i) {
|
||||
seq->notes().insert(*i);
|
||||
}
|
||||
|
||||
static const FrameTime delay = 1000;
|
||||
static const uint32_t cc_type = 1;
|
||||
|
||||
boost::shared_ptr<Control> c = seq->control(MIDI::ContinuousController(cc_type, 1, 1), true);
|
||||
CPPUNIT_ASSERT(c);
|
||||
|
||||
double min, max, normal;
|
||||
MIDI::controller_range(min, max, normal);
|
||||
|
||||
// Make a ramp like /\ from min to max and back to min
|
||||
c->set_float(min, true, 0);
|
||||
c->set_float(max, true, delay);
|
||||
c->set_float(min, true, 2*delay);
|
||||
|
||||
CCTestSink<Time> sink(cc_type);
|
||||
|
||||
// Test discrete (lack of) interpolation
|
||||
c->list()->set_interpolation(ControlList::Discrete);
|
||||
for (MySequence<Time>::const_iterator i = seq->begin(); i != seq->end(); ++i) {
|
||||
sink.write(i->time(), i->event_type(), i->size(), i->buffer());
|
||||
}
|
||||
CPPUNIT_ASSERT(sink.events.size() == 3);
|
||||
CPPUNIT_ASSERT(sink.events[0].first == 0);
|
||||
CPPUNIT_ASSERT(sink.events[0].second == 0);
|
||||
CPPUNIT_ASSERT(sink.events[1].first == 1000);
|
||||
CPPUNIT_ASSERT(sink.events[1].second == 127);
|
||||
CPPUNIT_ASSERT(sink.events[2].first == 2000);
|
||||
CPPUNIT_ASSERT(sink.events[2].second == 0);
|
||||
sink.events.clear();
|
||||
CPPUNIT_ASSERT(sink.events.size() == 0);
|
||||
|
||||
// Test linear interpolation
|
||||
c->list()->set_interpolation(ControlList::Linear);
|
||||
for (MySequence<Time>::const_iterator i = seq->begin(); i != seq->end(); ++i) {
|
||||
sink.write(i->time(), i->event_type(), i->size(), i->buffer());
|
||||
}
|
||||
CPPUNIT_ASSERT(sink.events.size() == 128 * 2 - 1);
|
||||
Time last_time = 0;
|
||||
int16_t last_value = -1;
|
||||
bool ascending = true;
|
||||
for (CCTestSink<Time>::Events::const_iterator i = sink.events.begin();
|
||||
i != sink.events.end(); ++i) {
|
||||
CPPUNIT_ASSERT(last_time == 0 || i->first > last_time);
|
||||
if (last_value == 127) {
|
||||
ascending = false;
|
||||
}
|
||||
if (ascending) {
|
||||
CPPUNIT_ASSERT(i->second == last_value + 1);
|
||||
} else {
|
||||
CPPUNIT_ASSERT(i->second == last_value - 1);
|
||||
}
|
||||
last_time = i->first;
|
||||
last_value = i->second;
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ using namespace Evoral;
|
||||
|
||||
class DummyTypeMap : public TypeMap {
|
||||
public:
|
||||
|
||||
enum DummyEventType {
|
||||
NOTE,
|
||||
CONTROL,
|
||||
@ -92,12 +91,31 @@ private:
|
||||
Time _last_event_time;
|
||||
};
|
||||
|
||||
template<typename Time>
|
||||
class CCTestSink : public EventSink<Time> {
|
||||
public:
|
||||
CCTestSink(uint32_t t) : cc_type(t) {}
|
||||
|
||||
virtual uint32_t write(Time time, EventType type, uint32_t size, const uint8_t* buf) {
|
||||
if (type == cc_type) {
|
||||
CPPUNIT_ASSERT(size == 3);
|
||||
events.push_back(make_pair(time, buf[2]));
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
typedef std::vector< std::pair<Time, uint8_t> > Events;
|
||||
Events events;
|
||||
uint32_t cc_type;
|
||||
};
|
||||
|
||||
class SequenceTest : public CppUnit::TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE (SequenceTest);
|
||||
CPPUNIT_TEST (createTest);
|
||||
CPPUNIT_TEST (preserveEventOrderingTest);
|
||||
CPPUNIT_TEST (iteratorSeekTest);
|
||||
CPPUNIT_TEST (controlInterpolationTest);
|
||||
CPPUNIT_TEST_SUITE_END ();
|
||||
|
||||
public:
|
||||
@ -125,6 +143,7 @@ public:
|
||||
void createTest ();
|
||||
void preserveEventOrderingTest ();
|
||||
void iteratorSeekTest ();
|
||||
void controlInterpolationTest ();
|
||||
|
||||
private:
|
||||
DummyTypeMap* type_map;
|
||||
|
Loading…
Reference in New Issue
Block a user