Akihiro Sagawa : midimap: Handle MIDI running status.
Alexandre Julliard
julliard at winehq.org
Thu May 26 15:46:27 CDT 2022
Module: wine
Branch: master
Commit: 4c535a7f7546f2dfe504c47dfc416d3cdd0a5ab0
URL: https://source.winehq.org/git/wine.git/?a=commit;h=4c535a7f7546f2dfe504c47dfc416d3cdd0a5ab0
Author: Akihiro Sagawa <sagawa.aki at gmail.com>
Date: Thu May 26 23:38:43 2022 +0900
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 at gmail.com>
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/midimap/midimap.c | 30 +++++++++++++++++++++++++++---
1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/dlls/midimap/midimap.c b/dlls/midimap/midimap.c
index 12555f5309a..e04fe721364 100644
--- a/dlls/midimap/midimap.c
+++ b/dlls/midimap/midimap.c
@@ -101,6 +101,7 @@ typedef struct tagMIDIMAPDATA
struct tagMIDIMAPDATA* self;
MIDIOUTPORT* ChannelMap[16];
MIDIOPENDESC midiDesc;
+ BYTE runningStatus;
WORD wCbFlags;
} MIDIMAPDATA;
@@ -301,6 +302,7 @@ static DWORD modOpen(DWORD_PTR *lpdwUser, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
mom->self = mom;
mom->wCbFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
mom->midiDesc = *lpDesc;
+ mom->runningStatus = 0;
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;
}
}
+ mom->runningStatus = 0;
lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
lpMidiHdr->dwFlags |= MHDR_DONE;
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)
{
- BYTE lb = LOBYTE(LOWORD(dwParam));
- WORD chn = lb & 0x0F;
+ BYTE status = LOBYTE(LOWORD(dwParam));
+ WORD chn;
DWORD ret = MMSYSERR_NOERROR;
if (MIDIMAP_IsBadData(mom))
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;
- switch (lb & 0xF0)
+ switch (status & 0xF0)
{
case 0x80:
case 0x90:
@@ -423,6 +441,7 @@ static DWORD modData(MIDIMAPDATA* mom, DWORD_PTR dwParam)
}
ret = midiOutShortMsg(mom->ChannelMap[chn]->hMidi, dwParam);
}
+ mom->runningStatus = status;
break;
case 0xF0:
for (chn = 0; chn < 16; chn++)
@@ -430,6 +449,9 @@ static DWORD modData(MIDIMAPDATA* mom, DWORD_PTR dwParam)
if (mom->ChannelMap[chn]->loaded > 0)
ret = midiOutShortMsg(mom->ChannelMap[chn]->hMidi, dwParam);
}
+ /* system common message */
+ if (status <= 0xF7)
+ mom->runningStatus = 0;
break;
default:
FIXME("ooch %Ix\n", dwParam);
@@ -511,6 +533,8 @@ static DWORD modReset(MIDIMAPDATA* mom)
if (ret != MMSYSERR_NOERROR) break;
}
}
+ mom->runningStatus = 0;
+
return ret;
}
More information about the wine-cvs
mailing list