1 #include <cassert>
2 #include <sigc++/sigc++.h>
3 #include <cppunit/TestFixture.h>
4 #include <cppunit/extensions/HelperMacros.h>
5 #include "temporal/beats.h"
6 #include "evoral/Sequence.h"
7 #include "evoral/TypeMap.h"
8 #include "evoral/EventSink.h"
9 #include "evoral/midi_events.h"
10 #include "evoral/Control.h"
11 
12 using namespace Evoral;
13 
14 class DummyTypeMap : public TypeMap {
15 public:
16 	enum DummyEventType {
17 		NOTE,
18 		CONTROL,
19 		SYSEX
20 	};
21 
~DummyTypeMap()22 	~DummyTypeMap() {}
23 
type_is_midi(uint32_t)24 	bool type_is_midi (uint32_t /*type*/) const { return true; }
25 
parameter_midi_type(const Parameter & param)26 	uint8_t parameter_midi_type(const Parameter& param) const {
27 		switch (param.type()) {
28 		case CONTROL:       return MIDI_CMD_CONTROL;
29 		case SYSEX:         return MIDI_CMD_COMMON_SYSEX;
30 		default:            return 0;
31 		};
32 	}
33 
midi_parameter_type(const uint8_t * buf,uint32_t len)34 	virtual ParameterType midi_parameter_type(const uint8_t* buf, uint32_t len) const {
35 		switch (buf[0] & 0xF0) {
36 		case MIDI_CMD_CONTROL:      return CONTROL;
37 		case MIDI_CMD_COMMON_SYSEX: return SYSEX;
38 		case MIDI_CMD_NOTE_ON:      return NOTE;
39 		case MIDI_CMD_NOTE_OFF:     return NOTE;
40 		default: return 0;
41 		}
42 	}
43 
descriptor(const Parameter & param)44 	ParameterDescriptor descriptor(const Parameter& param) const {
45 		Evoral::ParameterDescriptor desc;
46 		desc.upper = 127;
47 		desc.rangesteps = 128;
48 		return desc;
49 	}
50 
to_symbol(const Parameter &)51 	std::string to_symbol(const Parameter& /*param*/) const { return "control"; }
52 };
53 
54 template<typename Time>
55 class MySequence : public Sequence<Time> {
56 public:
MySequence(DummyTypeMap & map)57 	MySequence(DummyTypeMap&map) : Sequence<Time>(map) {}
MySequence(const MySequence & copy)58 	MySequence(const MySequence& copy) : ControlSet(copy), Sequence<Time>(copy) {}
59 
find_next_event(double start,double end,ControlEvent & ev,bool only_active)60 	virtual bool find_next_event(double start, double end, ControlEvent& ev, bool only_active) const { return false; }
61 
control_factory(const Parameter & param)62 	boost::shared_ptr<Control> control_factory(const Parameter& param) {
63 		Evoral::ParameterDescriptor desc;
64 		desc.upper = 127;
65 		desc.rangesteps = 128;
66 		boost::shared_ptr<ControlList> list(new ControlList(param, desc));
67 		return boost::shared_ptr<Control>(new Control(param, desc, list));
68 	}
69 };
70 
71 template<typename Time>
72 class TestSink : public EventSink<Time> {
73 public:
TestSink()74 	TestSink() : _last_event_time(-1) {}
75 
76 	/// return value, time, type, size, buffer
77 	sigc::signal<uint32_t, Time, EventType, uint32_t, const uint8_t*> writing;
78 
write(Time time,EventType type,uint32_t size,const uint8_t * buf)79 	virtual uint32_t write(Time time, EventType type, uint32_t size, const uint8_t* buf) {
80 		//std::cerr << "last event time: " << _last_event_time << " time: " << time << std::endl;
81 		uint32_t result = writing(time, type, size, buf);
82 		_last_event_time = time;
83 		return result;
84 	}
85 
assertLastEventTimeEarlier(Time time,EventType,uint32_t,const uint8_t *)86 	uint32_t assertLastEventTimeEarlier(
87 			Time time, EventType /*type*/, uint32_t /*size*/, const uint8_t* /*buf*/) {
88 		CPPUNIT_ASSERT(_last_event_time <= time);
89 		return 0;
90 	}
91 
last_event_time()92 	Time last_event_time() const { return _last_event_time; }
93 
94 private:
95 	Time _last_event_time;
96 };
97 
98 template<typename Time>
99 class CCTestSink : public EventSink<Time> {
100 public:
CCTestSink(uint32_t t)101 	CCTestSink(uint32_t t) : cc_type(t) {}
102 
write(Time time,EventType type,uint32_t size,const uint8_t * buf)103 	virtual uint32_t write(Time time, EventType type, uint32_t size, const uint8_t* buf) {
104 		if (type == cc_type) {
105 			CPPUNIT_ASSERT_EQUAL((uint32_t)3, size);
106 			events.push_back(std::make_pair(time, buf[2]));
107 		}
108 		return size;
109 	}
110 
111 	typedef std::vector< std::pair<Time, uint8_t> > Events;
112 	Events events;
113 	uint32_t cc_type;
114 };
115 
116 class SequenceTest : public CppUnit::TestFixture
117 {
118 	CPPUNIT_TEST_SUITE (SequenceTest);
119 	CPPUNIT_TEST (createTest);
120 	CPPUNIT_TEST (copyTest);
121 	CPPUNIT_TEST (preserveEventOrderingTest);
122 	CPPUNIT_TEST (iteratorSeekTest);
123 	CPPUNIT_TEST (controlInterpolationTest);
124 	CPPUNIT_TEST_SUITE_END ();
125 
126 public:
127 	typedef Temporal::Beats Time;
128 	typedef std::vector< boost::shared_ptr< Note<Time> > > Notes;
129 
setUp()130 	void setUp () {
131 		type_map = new DummyTypeMap();
132 		assert(type_map);
133 		seq = new MySequence<Time>(*type_map);
134 		assert(seq);
135 
136 		for (int i = 0; i < 12; i++) {
137 			test_notes.push_back(
138 				boost::shared_ptr<Note<Time> >(
139 					new Note<Time>(0, Time(i * 100), Time(100), 64 + i, 64)));
140 		}
141 	}
142 
tearDown()143 	void tearDown () {
144 		test_notes.clear();
145 		delete seq;
146 		delete type_map;
147 	}
148 
149 	void createTest ();
150 	void copyTest ();
151 	void preserveEventOrderingTest ();
152 	void iteratorSeekTest ();
153 	void controlInterpolationTest ();
154 
155 private:
156 	DummyTypeMap*       type_map;
157 	MySequence<Time>*   seq;
158 
159 	Notes test_notes;
160 };
161