midiin_device: handle channel remapping at playback time instead of load time, also small fix to sysex event parsing (#9019)

This commit is contained in:
Devin Acker 2021-12-19 14:06:38 -05:00 committed by GitHub
parent f518863ba3
commit 039e7448ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 15 deletions

View File

@ -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<u8 const *>(ptr()), length(), m_config->read()))
if (m_sequence.parse(reinterpret_cast<u8 const *>(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());
}

View File

@ -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<midi_event> m_list;