diff options
| author | 2023-10-20 19:21:52 -0400 | |
|---|---|---|
| committer | 2023-10-20 19:21:52 -0400 | |
| commit | 64bc63a65545260210f6e6e2d0c5f29c4b2f96fa (patch) | |
| tree | 3e1e1ad8808d41bdb019cce69ba56cf2a9d10a75 /src | |
| parent | 6f1abb62220a00a05bd671577ea36865bc6333cf (diff) | |
midiin_device: support loading sysex dumps (#11625)
Diffstat (limited to 'src')
| -rw-r--r-- | src/devices/imagedev/midiin.cpp | 35 | ||||
| -rw-r--r-- | src/devices/imagedev/midiin.h | 3 |
2 files changed, 33 insertions, 5 deletions
diff --git a/src/devices/imagedev/midiin.cpp b/src/devices/imagedev/midiin.cpp index bc5499f0f0d..189bd85d20c 100644 --- a/src/devices/imagedev/midiin.cpp +++ b/src/devices/imagedev/midiin.cpp @@ -470,10 +470,8 @@ std::error_condition midiin_device::midi_sequence::parse(util::random_read &stre // catch errors to make parsing easier try { - // if not a RIFF-encoed MIDI, just parse as-is - if (buffer.dword_le() != fourcc_le("RIFF")) - parse_midi_data(buffer.reset()); - else + const u32 type = buffer.dword_le(); + if (type == fourcc_le("RIFF")) { // check the RIFF type and size u32 riffsize = buffer.dword_le(); @@ -495,6 +493,11 @@ std::error_condition midiin_device::midi_sequence::parse(util::random_read &stre } } } + else if ((u8)type == 0xf0) + parse_sysex_data(buffer.reset()); + else + parse_midi_data(buffer.reset()); + m_iterator = m_list.begin(); return std::error_condition(); } @@ -639,3 +642,27 @@ u32 midiin_device::midi_sequence::parse_track_data(midi_parser &buffer, u32 star } return curtick; } + +//------------------------------------------------- +// parse_sysex_data - parse a sysex dump into a +// single MIDI event +//------------------------------------------------- + +void midiin_device::midi_sequence::parse_sysex_data(midi_parser &buffer) +{ + u32 msg = 0; + attotime curtime; + while (!buffer.eob()) + { + midi_event &event = event_at(msg++); + event.set_time(curtime); + + u8 data = 0; + while (!buffer.eob() && data != 0xf7) + event.append(data = buffer.byte()); + + // add 100 ms between the end of this sysex and the start of the next one, if there is one + curtime += attotime::from_ticks((u64)10 * event.data().size(), 31250) + + attotime::from_msec(100); + } +} diff --git a/src/devices/imagedev/midiin.h b/src/devices/imagedev/midiin.h index 0c65e527724..2bcba3720cc 100644 --- a/src/devices/imagedev/midiin.h +++ b/src/devices/imagedev/midiin.h @@ -45,7 +45,7 @@ public: virtual bool is_writeable() const noexcept override { return false; } virtual bool is_creatable() const noexcept override { return false; } virtual bool is_reset_on_load() const noexcept override { return false; } - virtual const char *file_extensions() const noexcept override { return "mid"; } + virtual const char *file_extensions() const noexcept override { return "mid,syx"; } virtual bool core_opens_image_file() const noexcept override { return false; } virtual const char *image_type_name() const noexcept override { return "midiin"; } virtual const char *image_brief_type_name() const noexcept override { return "min"; } @@ -173,6 +173,7 @@ private: midi_event &event_at(u32 tick); u32 parse_track_data(midi_parser &buffer, u32 start_tick); void parse_midi_data(midi_parser &buffer); + void parse_sysex_data(midi_parser &buffer); // internal state std::list<midi_event> m_list; |
