Commit 4c535a7f authored by Akihiro Sagawa's avatar Akihiro Sagawa Committed by Alexandre Julliard

midimap: Handle MIDI running status.

Wine's midiOutShortMsg() can't handle the MIDI message if the status byte is omitted. Omitting status byte is valid and called "running status". Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53003Signed-off-by: 's avatarAkihiro Sagawa <sagawa.aki@gmail.com> Signed-off-by: 's avatarAndrew Eikum <aeikum@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 99ce6e87
...@@ -101,6 +101,7 @@ typedef struct tagMIDIMAPDATA ...@@ -101,6 +101,7 @@ typedef struct tagMIDIMAPDATA
struct tagMIDIMAPDATA* self; struct tagMIDIMAPDATA* self;
MIDIOUTPORT* ChannelMap[16]; MIDIOUTPORT* ChannelMap[16];
MIDIOPENDESC midiDesc; MIDIOPENDESC midiDesc;
BYTE runningStatus;
WORD wCbFlags; WORD wCbFlags;
} MIDIMAPDATA; } MIDIMAPDATA;
...@@ -301,6 +302,7 @@ static DWORD modOpen(DWORD_PTR *lpdwUser, LPMIDIOPENDESC lpDesc, DWORD dwFlags) ...@@ -301,6 +302,7 @@ static DWORD modOpen(DWORD_PTR *lpdwUser, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
mom->self = mom; mom->self = mom;
mom->wCbFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK); mom->wCbFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
mom->midiDesc = *lpDesc; mom->midiDesc = *lpDesc;
mom->runningStatus = 0;
for (chn = 0; chn < 16; chn++) for (chn = 0; chn < 16; chn++)
{ {
...@@ -380,6 +382,7 @@ static DWORD modLongData(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD_PTR dwPara ...@@ -380,6 +382,7 @@ static DWORD modLongData(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD_PTR dwPara
if (ret != MMSYSERR_NOERROR) break; if (ret != MMSYSERR_NOERROR) break;
} }
} }
mom->runningStatus = 0;
lpMidiHdr->dwFlags &= ~MHDR_INQUEUE; lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
lpMidiHdr->dwFlags |= MHDR_DONE; lpMidiHdr->dwFlags |= MHDR_DONE;
MIDIMAP_NotifyClient(mom, MOM_DONE, (DWORD_PTR)lpMidiHdr, 0L); MIDIMAP_NotifyClient(mom, MOM_DONE, (DWORD_PTR)lpMidiHdr, 0L);
...@@ -388,16 +391,31 @@ static DWORD modLongData(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD_PTR dwPara ...@@ -388,16 +391,31 @@ static DWORD modLongData(MIDIMAPDATA* mom, LPMIDIHDR lpMidiHdr, DWORD_PTR dwPara
static DWORD modData(MIDIMAPDATA* mom, DWORD_PTR dwParam) static DWORD modData(MIDIMAPDATA* mom, DWORD_PTR dwParam)
{ {
BYTE lb = LOBYTE(LOWORD(dwParam)); BYTE status = LOBYTE(LOWORD(dwParam));
WORD chn = lb & 0x0F; WORD chn;
DWORD ret = MMSYSERR_NOERROR; DWORD ret = MMSYSERR_NOERROR;
if (MIDIMAP_IsBadData(mom)) if (MIDIMAP_IsBadData(mom))
return MMSYSERR_ERROR; return MMSYSERR_ERROR;
if (status < 0x80)
{
if (mom->runningStatus)
{
status = mom->runningStatus;
dwParam = ((LOWORD(dwParam) << 8) | status);
}
else
{
FIXME("ooch %Ix\n", dwParam);
return MMSYSERR_NOERROR;
}
}
chn = status & 0x0F;
if (!mom->ChannelMap[chn]) return MMSYSERR_NOERROR; if (!mom->ChannelMap[chn]) return MMSYSERR_NOERROR;
switch (lb & 0xF0) switch (status & 0xF0)
{ {
case 0x80: case 0x80:
case 0x90: case 0x90:
...@@ -423,6 +441,7 @@ static DWORD modData(MIDIMAPDATA* mom, DWORD_PTR dwParam) ...@@ -423,6 +441,7 @@ static DWORD modData(MIDIMAPDATA* mom, DWORD_PTR dwParam)
} }
ret = midiOutShortMsg(mom->ChannelMap[chn]->hMidi, dwParam); ret = midiOutShortMsg(mom->ChannelMap[chn]->hMidi, dwParam);
} }
mom->runningStatus = status;
break; break;
case 0xF0: case 0xF0:
for (chn = 0; chn < 16; chn++) for (chn = 0; chn < 16; chn++)
...@@ -430,6 +449,9 @@ static DWORD modData(MIDIMAPDATA* mom, DWORD_PTR dwParam) ...@@ -430,6 +449,9 @@ static DWORD modData(MIDIMAPDATA* mom, DWORD_PTR dwParam)
if (mom->ChannelMap[chn]->loaded > 0) if (mom->ChannelMap[chn]->loaded > 0)
ret = midiOutShortMsg(mom->ChannelMap[chn]->hMidi, dwParam); ret = midiOutShortMsg(mom->ChannelMap[chn]->hMidi, dwParam);
} }
/* system common message */
if (status <= 0xF7)
mom->runningStatus = 0;
break; break;
default: default:
FIXME("ooch %Ix\n", dwParam); FIXME("ooch %Ix\n", dwParam);
...@@ -511,6 +533,8 @@ static DWORD modReset(MIDIMAPDATA* mom) ...@@ -511,6 +533,8 @@ static DWORD modReset(MIDIMAPDATA* mom)
if (ret != MMSYSERR_NOERROR) break; if (ret != MMSYSERR_NOERROR) break;
} }
} }
mom->runningStatus = 0;
return ret; return ret;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment