summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Devin Acker <d@revenant1.net>2023-10-20 19:21:52 -0400
committer GitHub <noreply@github.com>2023-10-20 19:21:52 -0400
commit64bc63a65545260210f6e6e2d0c5f29c4b2f96fa (patch)
tree3e1e1ad8808d41bdb019cce69ba56cf2a9d10a75 /src
parent6f1abb62220a00a05bd671577ea36865bc6333cf (diff)
midiin_device: support loading sysex dumps (#11625)
Diffstat (limited to 'src')
-rw-r--r--src/devices/imagedev/midiin.cpp35
-rw-r--r--src/devices/imagedev/midiin.h3
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;