[PATCH 1/5] midimap: Handle MIDI running status.
Andrew Eikum
aeikum at codeweavers.com
Thu May 26 11:17:34 CDT 2022
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
On Thu, May 26, 2022 at 11:38:43PM +0900, Akihiro Sagawa wrote:
> 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>
> ---
> 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-devel
mailing list