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