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