1 #include "SequenceTest.h"
2 #include <cassert>
3 
4 CPPUNIT_TEST_SUITE_REGISTRATION(SequenceTest);
5 
6 using namespace std;
7 using namespace Evoral;
8 
9 void
createTest()10 SequenceTest::createTest ()
11 {
12 	CPPUNIT_ASSERT_EQUAL(size_t(0), seq->sysexes().size());
13 	CPPUNIT_ASSERT_EQUAL(size_t(0), seq->notes().size());
14 	CPPUNIT_ASSERT(seq->notes().begin() == seq->notes().end());
15 }
16 
17 void
copyTest()18 SequenceTest::copyTest ()
19 {
20 	DummyTypeMap map;
21 	MySequence<Time> a(map);
22 	for (Notes::const_iterator i = test_notes.begin(); i != test_notes.end(); ++i) {
23 		a.notes().insert(*i);
24 	}
25 
26 	MySequence<Time> b(a);
27 	CPPUNIT_ASSERT_EQUAL(b.notes().size(), a.notes().size());
28 }
29 
30 void
preserveEventOrderingTest()31 SequenceTest::preserveEventOrderingTest ()
32 {
33 	vector< boost::shared_ptr< Event<Time> > > inserted_events;
34 
35 	seq->start_write();
36 
37 	for (Notes::const_iterator i = test_notes.begin(); i != test_notes.end(); ++i) {
38 		uint8_t buffer[3];
39 		Event<Time>* event = new Event<Time>(
40 			(Evoral::EventType)DummyTypeMap::CONTROL, (*i)->on_event().time(), 3, buffer, true
41 		);
42 
43 		event->buffer()[0] = MIDI_CMD_CONTROL;
44 		event->buffer()[1] = event->time().to_double() / 1000;
45 		event->buffer()[2] = event->time().to_double() / 1000;
46 
47 		boost::shared_ptr<Event<Time> > event_ptr(event);
48 
49 		seq->append((*i)->on_event(), next_event_id ());
50 		inserted_events.push_back(
51 				boost::shared_ptr<Event<Time> >(
52 						new Event<Time>((*i)->on_event(), true)
53 		));
54 
55 		seq->append(*event_ptr, next_event_id ());
56 		inserted_events.push_back(event_ptr);
57 
58 		seq->append((*i)->off_event(), next_event_id ());
59 		inserted_events.push_back(
60 				boost::shared_ptr<Event<Time> >(
61 						new Event<Time>((*i)->off_event(), true)
62 		));
63 	}
64 
65 	seq->end_write (Sequence<Time>::Relax);
66 
67 	TestSink<Time> sink;
68 	sink.writing.connect(sigc::mem_fun(&sink, &TestSink<Time>::assertLastEventTimeEarlier));
69 
70 
71 	for (MySequence<Time>::const_iterator i = seq->begin(); i != seq->end(); ++i) {
72 		sink.write(i->time(), i->event_type(), i->size(), i->buffer());
73 	}
74 
75 	CPPUNIT_ASSERT_EQUAL(size_t(12), test_notes.size());
76 }
77 
78 void
iteratorSeekTest()79 SequenceTest::iteratorSeekTest ()
80 {
81 	size_t num_notes = 0;
82 
83 	seq->clear();
84 
85 	for (Notes::const_iterator i = test_notes.begin(); i != test_notes.end(); ++i) {
86 		seq->notes().insert(*i);
87 	}
88 
89 	// Iterate over all notes
90 	bool on = true;
91 	for (Sequence<Time>::const_iterator i = seq->begin(Time(600)); i != seq->end(); ++i) {
92 		if (on) {
93 			CPPUNIT_ASSERT(i->is_note_on());
94 			CPPUNIT_ASSERT_EQUAL(i->time(), Time((num_notes + 6) * 100));
95 			++num_notes;
96 			on = false;
97 		} else {
98 			CPPUNIT_ASSERT(i->is_note_off());
99 			on = true;
100 		}
101 	}
102 
103 	CPPUNIT_ASSERT_EQUAL(size_t(6), num_notes);
104 
105 	// Test invalidation
106 	Sequence<Time>::const_iterator i = seq->begin(Time(600));
107 	std::set< boost::weak_ptr< Note<Time> > > active_notes;
108 	i.invalidate(&active_notes);
109 	CPPUNIT_ASSERT_EQUAL((size_t)1, active_notes.size());
110 
111 	// Test resuming after invalidation
112 	i = seq->begin(Time(601), false, std::set<Evoral::Parameter>(), &active_notes);
113 	CPPUNIT_ASSERT(i->is_note_off());
114 	on = false;
115 	num_notes = 1;
116 	for (; i != seq->end(); ++i) {
117 		if (on) {
118 			CPPUNIT_ASSERT(i->is_note_on());
119 			CPPUNIT_ASSERT_EQUAL(Time((num_notes + 6) * 100), i->time());
120 			++num_notes;
121 			on = false;
122 		} else {
123 			CPPUNIT_ASSERT(i->is_note_off());
124 			on = true;
125 		}
126 	}
127 
128 	CPPUNIT_ASSERT_EQUAL(size_t(6), num_notes);
129 
130 	// Test equality of copied iterators
131 	i = seq->begin();
132 	++i;
133 	Sequence<Time>::const_iterator j = i;
134 	CPPUNIT_ASSERT(i == j);
135 }
136 
137 void
controlInterpolationTest()138 SequenceTest::controlInterpolationTest ()
139 {
140 	seq->clear();
141 
142 	static const uint64_t delay   = 1000;
143 	static const uint32_t cc_type = 1;
144 
145 	boost::shared_ptr<Control> c = seq->control(Parameter(cc_type, 1, 1), true);
146 	CPPUNIT_ASSERT(c);
147 
148 	double min = 0.0;
149 	double max = 127.0;
150 
151 	// Make a ramp like /\ from min to max and back to min
152 	c->set_double(min, 0, true);
153 	c->set_double(max, delay, true);
154 	c->set_double(min, 2*delay, true);
155 
156 	CCTestSink<Time> sink(cc_type);
157 
158 	// Test discrete (lack of) interpolation
159 	c->list()->set_interpolation(ControlList::Discrete);
160 	for (MySequence<Time>::const_iterator i = seq->begin(); i != seq->end(); ++i) {
161 		sink.write(i->time(), i->event_type(), i->size(), i->buffer());
162 	}
163 	CPPUNIT_ASSERT_EQUAL((size_t)3, sink.events.size());
164 	CPPUNIT_ASSERT_EQUAL(Time(0), sink.events[0].first);
165 	CPPUNIT_ASSERT_EQUAL((uint8_t)0, sink.events[0].second);
166 	CPPUNIT_ASSERT_EQUAL(Time(1000), sink.events[1].first);
167 	CPPUNIT_ASSERT_EQUAL((uint8_t)127, sink.events[1].second);
168 	CPPUNIT_ASSERT_EQUAL(Time(2000), sink.events[2].first);
169 	CPPUNIT_ASSERT_EQUAL((uint8_t)0, sink.events[2].second);
170 	sink.events.clear();
171 	CPPUNIT_ASSERT_EQUAL((size_t)0, sink.events.size());
172 
173 	// Test linear interpolation
174 	c->list()->set_interpolation(ControlList::Linear);
175 	for (MySequence<Time>::const_iterator i = seq->begin(); i != seq->end(); ++i) {
176 		sink.write(i->time(), i->event_type(), i->size(), i->buffer());
177 	}
178 	CPPUNIT_ASSERT_EQUAL((size_t)(128 * 2 - 1), sink.events.size());
179 	Time    last_time(0);
180 	int16_t last_value = -1;
181 	bool    ascending  = true;
182 	for (CCTestSink<Time>::Events::const_iterator i = sink.events.begin();
183 			i != sink.events.end(); ++i) {
184 		CPPUNIT_ASSERT(last_time == 0 || i->first > last_time);
185 		if (last_value == 127) {
186 			ascending = false;
187 		}
188 		if (ascending) {
189 			CPPUNIT_ASSERT_EQUAL((int)i->second, last_value + 1);
190 		} else {
191 			CPPUNIT_ASSERT_EQUAL((int)i->second, last_value - 1);
192 		}
193 		last_time = i->first;
194 		last_value = i->second;
195 	}
196 }
197