From 6fc03d481b07a825e46f7de4e7696dfd171ce39f Mon Sep 17 00:00:00 2001 From: AJR Date: Sat, 9 Apr 2022 22:34:31 -0400 Subject: midiin: Use util::random_read rather than buffer pointer in MIDI file parser --- src/devices/imagedev/midiin.cpp | 100 +++++++++++++++++++++++++++++++++++++--- src/devices/imagedev/midiin.h | 16 +++---- 2 files changed, 101 insertions(+), 15 deletions(-) diff --git a/src/devices/imagedev/midiin.cpp b/src/devices/imagedev/midiin.cpp index 7ee14882a2d..3c2ad7f2fa1 100644 --- a/src/devices/imagedev/midiin.cpp +++ b/src/devices/imagedev/midiin.cpp @@ -173,7 +173,7 @@ image_init_result midiin_device::call_load() // if the parsing succeeds, schedule the start to happen at least // 10 seconds after starting to allow the keyboards to initialize // TODO: this should perhaps be a driver-configurable parameter? - if (m_sequence.parse(reinterpret_cast(ptr()), length())) + if (m_sequence.parse(image_core_file(), length())) { m_sequence_start = std::max(machine().time(), attotime(10, 0)); m_timer->adjust(attotime::zero); @@ -273,8 +273,8 @@ static constexpr u32 fourcc_le(char const *string) // midi_parser - constructor //------------------------------------------------- -midiin_device::midi_parser::midi_parser(u8 const *data, u32 length, u32 offset) : - m_data(data), +midiin_device::midi_parser::midi_parser(util::random_read &stream, u32 length, u32 offset) : + m_stream(stream), m_length(length), m_offset(offset) { @@ -290,7 +290,7 @@ midiin_device::midi_parser::midi_parser(u8 const *data, u32 length, u32 offset) midiin_device::midi_parser midiin_device::midi_parser::subset(u32 length) { check_bounds(length); - midi_parser result(m_data + m_offset, length, 0); + midi_parser result(m_stream, m_offset + length, m_offset); m_offset += length; return result; } @@ -327,6 +327,91 @@ u32 midiin_device::midi_parser::variable() } +//------------------------------------------------- +// byte - read 8 bits of data +//------------------------------------------------- + +u8 midiin_device::midi_parser::byte() +{ + check_bounds(1); + + u8 result = 0; + std::size_t actual = 0; + if (m_stream.read_at(m_offset, &result, 1, actual) || actual != 1) + throw error("Error reading data"); + m_offset++; + return result; +} + + +//------------------------------------------------- +// word_be - read 16 bits of big-endian data +//------------------------------------------------- + +u16 midiin_device::midi_parser::word_be() +{ + check_bounds(2); + + u16 result = 0; + std::size_t actual = 0; + if (m_stream.read_at(m_offset, &result, 2, actual) || actual != 2) + throw error("Error reading data"); + m_offset += 2; + return big_endianize_int16(result); +} + + +//------------------------------------------------- +// triple_be - read 24 bits of big-endian data +//------------------------------------------------- + +u32 midiin_device::midi_parser::triple_be() +{ + check_bounds(3); + + u32 result = 0; + std::size_t actual = 0; + if (m_stream.read_at(m_offset, &result, 3, actual) || actual != 3) + throw error("Error reading data"); + m_offset += 3; + return big_endianize_int32(result) >> 8; +} + + +//------------------------------------------------- +// dword_be - read 32 bits of big-endian data +//------------------------------------------------- + +u32 midiin_device::midi_parser::dword_be() +{ + check_bounds(4); + + u32 result = 0; + std::size_t actual = 0; + if (m_stream.read_at(m_offset, &result, 4, actual) || actual != 4) + throw error("Error reading data"); + m_offset += 4; + return big_endianize_int32(result); +} + + +//------------------------------------------------- +// dword_le - read 32 bits of little-endian data +//------------------------------------------------- + +u32 midiin_device::midi_parser::dword_le() +{ + check_bounds(4); + + u32 result = 0; + std::size_t actual = 0; + if (m_stream.read_at(m_offset, &result, 4, actual) || actual != 4) + throw error("Error reading data"); + m_offset += 4; + return little_endianize_int32(result); +} + + //------------------------------------------------- // check_bounds - check to see if we have at least // 'length' bytes left to consume; if not, @@ -364,13 +449,13 @@ midiin_device::midi_event &midiin_device::midi_sequence::event_at(u32 tick) // parse - parse a MIDI sequence from a buffer //------------------------------------------------- -bool midiin_device::midi_sequence::parse(u8 const *data, u32 length) +bool midiin_device::midi_sequence::parse(util::random_read &stream, u32 length) { // start with an empty list of events m_list.clear(); // by default parse the whole data - midi_parser buffer(data, length, 0); + midi_parser buffer(stream, length, 0); // catch errors to make parsing easier try @@ -403,8 +488,9 @@ bool midiin_device::midi_sequence::parse(u8 const *data, u32 length) m_iterator = m_list.begin(); return true; } - catch (midi_parser::error &) + catch (midi_parser::error &err) { + osd_printf_error("MIDI file error: %s\n", err.description()); m_list.clear(); m_iterator = m_list.begin(); return false; diff --git a/src/devices/imagedev/midiin.h b/src/devices/imagedev/midiin.h index 4d65f8750fe..22cc81f7238 100644 --- a/src/devices/imagedev/midiin.h +++ b/src/devices/imagedev/midiin.h @@ -84,7 +84,7 @@ private: }; // construction - midi_parser(u8 const *data, u32 length, u32 offset); + midi_parser(util::random_read &stream, u32 length, u32 offset); // end of buffer? bool eob() const { return (m_offset >= m_length); } @@ -97,11 +97,11 @@ private: 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()); } + u8 byte(); + u16 word_be(); + u32 triple_be(); + u32 dword_be(); + u32 dword_le(); // special variable reader for MIDI u32 variable(); @@ -111,7 +111,7 @@ private: void check_bounds(u32 length); // internal state - u8 const *m_data; + util::random_read &m_stream; u32 m_length; u32 m_offset; }; @@ -154,7 +154,7 @@ private: void clear() { m_list.clear(); } // parse a new sequence - bool parse(u8 const *data, u32 length); + bool parse(util::random_read &stream, u32 length); // rewind to the start of time void rewind(attotime const &basetime); -- cgit v1.2.3