Module: wine Branch: oldstable Commit: bdddc8ac70e8e48f12def2dd8d66fb229d1ab37b URL: https://gitlab.winehq.org/wine/wine/-/commit/bdddc8ac70e8e48f12def2dd8d66fb2...
Author: Akihiro Sagawa sagawa.aki@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@gmail.com Signed-off-by: Andrew Eikum aeikum@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org (cherry picked from commit 4c535a7f7546f2dfe504c47dfc416d3cdd0a5ab0) Signed-off-by: Michael Stefaniuc mstefani@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 53eeadee915..a78da7aea42 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 %lx\n", dwParam); @@ -511,6 +533,8 @@ static DWORD modReset(MIDIMAPDATA* mom) if (ret != MMSYSERR_NOERROR) break; } } + mom->runningStatus = 0; + return ret; }