From 039e7448ce8ae4cd637a20704221ee4768112492 Mon Sep 17 00:00:00 2001 From: Devin Acker Date: Sun, 19 Dec 2021 14:06:38 -0500 Subject: [PATCH] midiin_device: handle channel remapping at playback time instead of load time, also small fix to sysex event parsing (#9019) --- src/devices/imagedev/midiin.cpp | 28 ++++++++++++++++------------ src/devices/imagedev/midiin.h | 6 +++--- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/devices/imagedev/midiin.cpp b/src/devices/imagedev/midiin.cpp index 30838a36eb9..84b9bfbfd0a 100644 --- a/src/devices/imagedev/midiin.cpp +++ b/src/devices/imagedev/midiin.cpp @@ -119,8 +119,15 @@ void midiin_device::device_timer(emu_timer &timer, device_timer_id id, int param // if it's time to process the current event, do it and advance if (curtime >= event->time()) { - for (auto &curbyte : event->data()) + const u8 force_channel = m_config->read(); + + for (u8 curbyte : event->data()) + { + if (force_channel <= 15 && curbyte >= 0x80 && curbyte < 0xf0) + curbyte = (curbyte & 0xf0) | force_channel; + xmit_char(curbyte); + } event = m_sequence.advance_event(); } @@ -166,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(), m_config->read())) + if (m_sequence.parse(reinterpret_cast(ptr()), length())) { m_sequence_start = std::max(machine().time(), attotime(10, 0)); m_timer->adjust(attotime::zero); @@ -357,7 +364,7 @@ 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, u8 force_channel) +bool midiin_device::midi_sequence::parse(u8 const *data, u32 length) { // start with an empty list of events m_list.clear(); @@ -370,7 +377,7 @@ bool midiin_device::midi_sequence::parse(u8 const *data, u32 length, u8 force_ch { // if not a RIFF-encoed MIDI, just parse as-is if (buffer.dword_le() != fourcc_le("RIFF")) - parse_midi_data(buffer.reset(), force_channel); + parse_midi_data(buffer.reset()); else { // check the RIFF type and size @@ -388,7 +395,7 @@ bool midiin_device::midi_sequence::parse(u8 const *data, u32 length, u8 force_ch midi_parser chunk = riffdata.subset(chunksize); if (chunktype == fourcc_le("data")) { - parse_midi_data(chunk, force_channel); + parse_midi_data(chunk); break; } } @@ -410,7 +417,7 @@ bool midiin_device::midi_sequence::parse(u8 const *data, u32 length, u8 force_ch // into tracks //------------------------------------------------- -void midiin_device::midi_sequence::parse_midi_data(midi_parser &buffer, u8 force_channel) +void midiin_device::midi_sequence::parse_midi_data(midi_parser &buffer) { // scan for syntactic correctness, and to find global state u32 headertype = buffer.dword_le(); @@ -447,7 +454,7 @@ void midiin_device::midi_sequence::parse_midi_data(midi_parser &buffer, u8 force // parse the track data midi_parser trackdata = buffer.subset(chunksize); - u32 numticks = parse_track_data(trackdata, curtick, force_channel); + u32 numticks = parse_track_data(trackdata, curtick); if (format == 2) curtick += numticks; } @@ -476,7 +483,7 @@ void midiin_device::midi_sequence::parse_midi_data(midi_parser &buffer, u8 force // add it to the buffer //------------------------------------------------- -u32 midiin_device::midi_sequence::parse_track_data(midi_parser &buffer, u32 start_tick, u8 force_channel) +u32 midiin_device::midi_sequence::parse_track_data(midi_parser &buffer, u32 start_tick) { u32 curtick = start_tick; u8 last_type = 0; @@ -501,10 +508,6 @@ u32 midiin_device::midi_sequence::parse_track_data(midi_parser &buffer, u32 star if (eclass != 15) { // simple events: all but program change and aftertouch have a second parameter - if (force_channel <= 15) - { - type = (type & 0xf0) | force_channel; - } event.append(type); event.append(buffer.byte()); if (eclass != 12 && eclass != 13) @@ -514,6 +517,7 @@ u32 midiin_device::midi_sequence::parse_track_data(midi_parser &buffer, u32 star { // handle non-meta events midi_parser eventdata = buffer.subset(buffer.variable()); + event.append(type); while (!eventdata.eob()) event.append(eventdata.byte()); } diff --git a/src/devices/imagedev/midiin.h b/src/devices/imagedev/midiin.h index a6e8e6d5958..70bc5987637 100644 --- a/src/devices/imagedev/midiin.h +++ b/src/devices/imagedev/midiin.h @@ -154,7 +154,7 @@ private: void clear() { m_list.clear(); } // parse a new sequence - bool parse(u8 const *data, u32 length, u8 force_channel); + bool parse(u8 const *data, u32 length); // rewind to the start of time void rewind(attotime const &basetime); @@ -165,8 +165,8 @@ private: private: // internal helpers midi_event &event_at(u32 tick); - u32 parse_track_data(midi_parser &buffer, u32 start_tick, u8 force_channel); - void parse_midi_data(midi_parser &buffer, u8 force_channel); + u32 parse_track_data(midi_parser &buffer, u32 start_tick); + void parse_midi_data(midi_parser &buffer); // internal state std::list m_list;