summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/imagedev/midiin.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/imagedev/midiin.h')
-rw-r--r--src/devices/imagedev/midiin.h109
1 files changed, 108 insertions, 1 deletions
diff --git a/src/devices/imagedev/midiin.h b/src/devices/imagedev/midiin.h
index ef8e9e315b0..28a0826fc0b 100644
--- a/src/devices/imagedev/midiin.h
+++ b/src/devices/imagedev/midiin.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:R. Belmont
+// copyright-holders:R. Belmont,Aaron Giles
/*********************************************************************
midiin.h
@@ -66,6 +66,113 @@ private:
uint8_t m_xmitring[XMIT_RING_SIZE];
int m_xmit_read, m_xmit_write;
bool m_tx_busy;
+
+ // internal helper class for parsing
+ class midi_parser
+ {
+ public:
+ // minimal error class
+ class error
+ {
+ public:
+ error(char const *description) : m_description(description) { }
+ char const *description() const { return m_description; }
+ private:
+ char const *m_description;
+ };
+
+ // construction
+ midi_parser(u8 const *data, u32 length, u32 offset);
+
+ // end of buffer?
+ bool eob() const { return (m_offset >= m_length); }
+
+ // create a subset
+ midi_parser subset(u32 length);
+
+ // change position within buffer
+ midi_parser &rewind(u32 count);
+ midi_parser &reset() { return rewind(m_offset); }
+
+ // read data of various sizes and endiannesses
+ u8 byte() { check_bounds(1); return m_data[m_offset++]; }
+ u16 word_be() { u16 result = byte() << 8; return result | byte(); }
+ u32 triple_be() { u32 result = word_be() << 8; return result | byte(); }
+ u32 dword_be() { u32 result = word_be() << 16; return result | word_be(); }
+ u32 dword_le() { return swapendian_int32(dword_be()); }
+
+ // special variable reader for MIDI
+ u32 variable();
+
+ private:
+ // internal helper
+ void check_bounds(u32 length);
+
+ // internal state
+ u8 const *m_data;
+ u32 m_length;
+ u32 m_offset;
+ };
+
+ // internal helper class reperesenting an event at a given
+ // time containing MIDI data
+ class midi_event
+ {
+ public:
+ // constructor
+ midi_event(u32 tick) :
+ m_tick(tick) { }
+
+ // simple getters
+ u32 tick() const { return m_tick; }
+ attotime const &time() const { return m_time; }
+ std::vector<u8> const &data() const { return m_data; }
+
+ // simple setters
+ void set_time(attotime const &time) { m_time = time; }
+
+ // append data to the buffer
+ midi_event &append(u8 byte) { m_data.push_back(byte); return *this; }
+
+ private:
+ // internal state
+ u32 m_tick;
+ attotime m_time;
+ std::vector<u8> m_data;
+ };
+
+ // internal helper class representing a MIDI sequence
+ class midi_sequence
+ {
+ public:
+ // constructor
+ midi_sequence() : m_iterator(m_list.begin()) { }
+
+ // clear the sequence
+ void clear() { m_list.clear(); }
+
+ // parse a new sequence
+ bool parse(u8 const *data, u32 length);
+
+ // rewind to the start of time
+ void rewind(attotime const &basetime);
+ midi_event *current_event() const { return (m_iterator == m_list.end()) ? nullptr : &(*m_iterator); }
+ midi_event *advance_event() { ++m_iterator; return current_event(); }
+ attotime const &duration() { return m_list.back().time(); }
+
+ private:
+ // internal helpers
+ midi_event &event_at(u32 tick);
+ u32 parse_track_data(midi_parser &buffer, u32 start_tick);
+ void parse_midi_data(midi_parser &buffer);
+
+ // internal state
+ std::list<midi_event> m_list;
+ std::list<midi_event>::iterator m_iterator;
+ };
+
+ midi_sequence m_sequence;
+ attotime m_sequence_start;
};
// device type definition