diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/evoral/evoral/Parameter.hpp | 2 | ||||
-rw-r--r-- | libs/evoral/src/Sequence.cpp | 8 | ||||
-rw-r--r-- | libs/evoral/test/SequenceTest.cpp | 67 | ||||
-rw-r--r-- | libs/evoral/test/SequenceTest.hpp | 21 |
4 files changed, 92 insertions, 6 deletions
diff --git a/libs/evoral/evoral/Parameter.hpp b/libs/evoral/evoral/Parameter.hpp index 8ffa5d30c7..6bd0954b8a 100644 --- a/libs/evoral/evoral/Parameter.hpp +++ b/libs/evoral/evoral/Parameter.hpp @@ -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> diff --git a/libs/evoral/src/Sequence.cpp b/libs/evoral/src/Sequence.cpp index 636816eb69..93eccb6cce 100644 --- a/libs/evoral/src/Sequence.cpp +++ b/libs/evoral/src/Sequence.cpp @@ -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; } diff --git a/libs/evoral/test/SequenceTest.cpp b/libs/evoral/test/SequenceTest.cpp index 0f6a30e5f1..2c5c17f4d8 100644 --- a/libs/evoral/test/SequenceTest.cpp +++ b/libs/evoral/test/SequenceTest.cpp @@ -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; + } +} diff --git a/libs/evoral/test/SequenceTest.hpp b/libs/evoral/test/SequenceTest.hpp index 8773c3774a..403ac0fd13 100644 --- a/libs/evoral/test/SequenceTest.hpp +++ b/libs/evoral/test/SequenceTest.hpp @@ -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; |