+
+void
+SequenceTest::controlInterpolationTest ()
+{
+ seq->clear();
+
+ for (Notes::const_iterator i = test_notes.begin(); i != test_notes.end(); ++i) {
+ seq->notes().insert(*i);
+ }
+
+ static const uint64_t delay = 1000;
+ static const uint32_t cc_type = 1;
+
+ boost::shared_ptr<Control> c = seq->control(Parameter(cc_type, 1, 1), true);
+ CPPUNIT_ASSERT(c);
+
+ double min = 0.0;
+ double max = 127.0;
+
+ // Make a ramp like /\ from min to max and back to min
+ c->set_double(min, 0, true);
+ c->set_double(max, delay, true);
+ c->set_double(min, 2*delay, true);
+
+ 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;
+ }
+}