mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 08:39:34 +00:00
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=53003 Signed-off-by: Akihiro Sagawa <sagawa.aki@gmail.com> Signed-off-by: Andrew Eikum <aeikum@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
99ce6e87a3
commit
4c535a7f75
|
@ -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)
|
||||||
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
|
||||||
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
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
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)
|
||||||
if (ret != MMSYSERR_NOERROR) break;
|
if (ret != MMSYSERR_NOERROR) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mom->runningStatus = 0;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue