--- np2/win9x/cmmidi.cpp 2005/02/09 20:11:35 1.6 +++ np2/win9x/cmmidi.cpp 2007/11/11 07:11:26 1.11 @@ -2,10 +2,15 @@ #include "np2.h" #include "mimpidef.h" #include "commng.h" -#if defined(VERMOUTH_LIB) +#if defined(VERMOUTH_LIB) || defined(MT32SOUND_DLL) #include "sound.h" +#endif +#if defined(VERMOUTH_LIB) #include "vermouth.h" #endif +#if defined(MT32SOUND_DLL) +#include "mt32snd.h" +#endif #include "keydisp.h" @@ -23,6 +28,10 @@ const OEMCHAR cmmidi_midimapper[] = OEMT #if defined(VERMOUTH_LIB) const OEMCHAR cmmidi_vermouth[] = OEMTEXT("VERMOUTH"); #endif +#if defined(MT32SOUND_DLL) +const OEMCHAR cmmidi_mt32sound[] = OEMTEXT("MT32Sound"); +#endif + const OEMCHAR *cmmidi_mdlname[12] = { OEMTEXT("MT-32"), OEMTEXT("CM-32L"), OEMTEXT("CM-64"), OEMTEXT("CM-300"), OEMTEXT("CM-500(LA)"), OEMTEXT("CM-500(GS)"), @@ -35,21 +44,22 @@ enum { MIDI_MT32 = 0, MIDI_CM32L, MIDI MIDI_GM, MIDI_GS, MIDI_XG, MIDI_OTHER}; static const UINT8 EXCV_MTRESET[] = { - 0xfe, 0xfe, 0xfe}; + 0xf0,0x41,0x10,0x16,0x12,0x7f,0x00,0x00,0x00,0x01,0xf7}; static const UINT8 EXCV_GMRESET[] = { - 0xf0, 0x7e, 0x7f, 0x09, 0x01, 0xf7}; + 0xf0,0x7e,0x7f,0x09,0x01,0xf7}; +static const UINT8 EXCV_GM2RESET[] = { + 0xf0,0x7e,0x7f,0x09,0x03,0xf7}; static const UINT8 EXCV_GSRESET[] = { - 0xf0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7f, 0x00, 0x41, 0xf7}; + 0xf0,0x41,0x10,0x42,0x12,0x40,0x00,0x7f,0x00,0x41,0xf7}; static const UINT8 EXCV_XGRESET[] = { - 0xf0, 0x43, 0x10, 0x4C, 0x00, 0x00, 0x7E, 0x00, 0xf7}; -static const UINT8 EXCV_GMVOLUME[] = { - 0xf0, 0x7F, 0x7F, 0x04, 0x01, 0x00, 0x00, 0xF7}; + 0xf0,0x43,0x10,0x4c,0x00,0x00,0x7e,0x00,0xf7}; enum { MIDI_EXCLUSIVE = 0xf0, MIDI_TIMECODE = 0xf1, MIDI_SONGPOS = 0xf2, MIDI_SONGSELECT = 0xf3, + MIDI_CABLESELECT = 0xf5, MIDI_TUNEREQUEST = 0xf6, MIDI_EOX = 0xf7, MIDI_TIMING = 0xf8, @@ -70,6 +80,9 @@ enum { #if defined(VERMOUTH_LIB) CMMIDI_VERMOUTH = 0x08, #endif +#if defined(MT32SOUND_DLL) + CMMIDI_MT32SOUND = 0x10, +#endif MIDICTRL_READY = 0, MIDICTRL_2BYTES, @@ -90,14 +103,24 @@ typedef struct { UINT8 ctrl[28]; } _MIDICH, *MIDICH; -struct _cmmidi { - UINT opened; - void (*outfn)(CMMIDI self, UINT32 msg); +typedef struct { HMIDIOUT hmidiout; - MIDIHDR hmidiouthdr; + MIDIHDR midihdr; +} OUTFNWIN32; + +typedef union { + OUTFNWIN32 win32; #if defined(VERMOUTH_LIB) MIDIHDL vermouth; #endif +} HMIDIFNOUT; + +struct _cmmidi { + UINT opened; + void (*shortout)(CMMIDI self, UINT32 msg); + void (*longout)(CMMIDI self, const UINT8 *msg, UINT leng); + HMIDIFNOUT out; + HMIDIIN hmidiin; MIDIHDR hmidiinhdr; UINT midictrl; @@ -139,7 +162,7 @@ static UINT8 midictrlindex[128]; // ---- -static BOOL getmidioutid(const OEMCHAR *midiout, UINT *ret) { +static BRESULT getmidioutid(const OEMCHAR *midiout, UINT *ret) { UINT num; UINT i; @@ -160,7 +183,7 @@ static BOOL getmidioutid(const OEMCHAR * return(FAILURE); } -static BOOL getmidiinid(const OEMCHAR *midiin, UINT *ret) { +static BRESULT getmidiinid(const OEMCHAR *midiin, UINT *ret) { UINT num; UINT i; @@ -186,50 +209,77 @@ static UINT module2number(const OEMCHAR UINT i; for (i=0; imidiexcvwait) { midi->midiexcvwait = 0; - while(midiOutUnprepareHeader(midi->hmidiout, &midi->hmidiouthdr, - sizeof(MIDIHDR)) == MIDIERR_STILLPLAYING); + while(midiOutUnprepareHeader(midi->out.win32.hmidiout, + &midi->out.win32.midihdr, + sizeof(midi->out.win32.midihdr)) + == MIDIERR_STILLPLAYING) { } } } -static void sendexclusive(CMMIDI midi, const UINT8 *buf, UINT leng) { +static void midi_win32short(CMMIDI midi, UINT32 msg) { - CopyMemory(midi->excvbuf, buf, leng); - midi->hmidiouthdr.lpData = (char *)midi->excvbuf; - midi->hmidiouthdr.dwFlags = 0; - midi->hmidiouthdr.dwBufferLength = leng; - midiOutPrepareHeader(midi->hmidiout, &midi->hmidiouthdr, sizeof(MIDIHDR)); - midiOutLongMsg(midi->hmidiout, &midi->hmidiouthdr, sizeof(MIDIHDR)); - midi->midiexcvwait = 1; + waitlastexclusiveout(midi); + midiOutShortMsg(midi->out.win32.hmidiout, (DWORD)msg); } -static void midiout_none(CMMIDI midi, UINT32 msg) { +static void midi_win32long(CMMIDI midi, const UINT8 *msg, UINT leng) { - (void)midi; - (void)msg; + waitlastexclusiveout(midi); + CopyMemory(midi->excvbuf, msg, leng); + midi->out.win32.midihdr.lpData = (char *)midi->excvbuf; + midi->out.win32.midihdr.dwFlags = 0; + midi->out.win32.midihdr.dwBufferLength = leng; + midiOutPrepareHeader(midi->out.win32.hmidiout, &midi->out.win32.midihdr, + sizeof(midi->out.win32.midihdr)); + midiOutLongMsg(midi->out.win32.hmidiout, &midi->out.win32.midihdr, + sizeof(midi->out.win32.midihdr)); + midi->midiexcvwait = 1; } -static void midiout_win32(CMMIDI midi, UINT32 msg) { - waitlastexclusiveout(midi); - midiOutShortMsg(midi->hmidiout, (DWORD)msg); -} +// ---- Vermouth #if defined(VERMOUTH_LIB) -static void midiout_vermouth(CMMIDI midi, UINT32 msg) { +static void midi_vermouthshort(CMMIDI midi, UINT32 msg) { + + sound_sync(); + midiout_shortmsg(midi->out.vermouth, msg); +} + +static void midi_vermouthlong(CMMIDI midi, const UINT8 *msg, UINT leng) { sound_sync(); - midiout_shortmsg(midi->vermouth, msg); + midiout_longmsg(midi->out.vermouth, msg, leng); } static void SOUNDCALL vermouth_getpcm(MIDIHDL hdl, SINT32 *pcm, UINT count) { @@ -254,11 +304,50 @@ const SINT32 *ptr; } #endif + +// ---- MT-32 + +#if defined(MT32SOUND_DLL) +static void midi_mt32short(CMMIDI midi, UINT32 msg) { + + sound_sync(); + mt32sound_shortmsg(msg); +} + +static void midi_mt32long(CMMIDI midi, const UINT8 *msg, UINT leng) { + + sound_sync(); + mt32sound_longmsg(msg, leng); +} + +static void SOUNDCALL mt32_getpcm(MIDIHDL hdl, SINT32 *pcm, UINT count) { + + mt32sound_mix32(pcm, count); +} +#endif + + + +// ---- + +static void midiallnoteoff(CMMIDI midi) { + + UINT i; + UINT8 msg[4]; + + for (i=0; i<0x10; i++) { + msg[0] = (UINT8)(0xb0 + i); + msg[1] = 0x7b; + msg[2] = 0x00; + keydisp_midi(msg); + midi->shortout(midi, MIDIOUTS3(msg)); + } +} + static void midireset(CMMIDI midi) { const UINT8 *excv; UINT excvsize; - UINT8 work[4]; switch(midi->midimodule) { case MIDI_GM: @@ -295,23 +384,9 @@ const UINT8 *excv; break; } if (excv) { - if (midi->opened & CMMIDI_MIDIOUT) { - waitlastexclusiveout(midi); - sendexclusive(midi, excv, excvsize); - } -#if defined(VERMOUTH_LIB) - else if (midi->opened & CMMIDI_VERMOUTH) { - midiout_longmsg(midi->vermouth, excv, excvsize); - } -#endif - } - - work[1] = 0x7b; - work[2] = 0x00; - for (work[0]=0xb0; work[0]<0xc0; work[0]++) { - keydisp_midi(work); - midi->outfn(midi, MIDIOUTS3(work)); + midi->longout(midi, excv, excvsize); } + midiallnoteoff(midi); } static void midisetparam(CMMIDI midi) { @@ -323,19 +398,19 @@ static void midisetparam(CMMIDI midi) { mch = midi->mch; for (i=0; i<16; i++, mch++) { if (mch->press != 0xff) { - midi->outfn(midi, MIDIOUTS(0xa0+i, mch->press, 0)); + midi->shortout(midi, MIDIOUTS(0xa0+i, mch->press, 0)); } if (mch->bend != 0xffff) { - midi->outfn(midi, (mch->bend << 8) + 0xe0+i); + midi->shortout(midi, (mch->bend << 8) + 0xe0+i); } for (j=0; jctrl[j+1] != 0xff) { - midi->outfn(midi, + midi->shortout(midi, MIDIOUTS(0xb0+i, midictrltbl[j], mch->ctrl[j+1])); } } if (mch->prog != 0xff) { - midi->outfn(midi, MIDIOUTS(0xc0+i, mch->prog, 0)); + midi->shortout(midi, MIDIOUTS(0xc0+i, mch->prog, 0)); } } } @@ -411,11 +486,12 @@ static UINT midiwrite(COMMNG self, UINT8 midi->midisyscnt = 2; break; - case MIDI_TUNEREQUEST: + case MIDI_CABLESELECT: midi->midictrl = MIDICTRL_SYSTEM; midi->midisyscnt = 1; break; +// case MIDI_TUNEREQUEST: // case MIDI_EOX: default: return(1); @@ -455,7 +531,7 @@ static UINT midiwrite(COMMNG self, UINT8 break; } keydisp_midi(midi->buffer); - midi->outfn(midi, MIDIOUTS2(midi->buffer)); + midi->shortout(midi, MIDIOUTS2(midi->buffer)); midi->midictrl = MIDICTRL_READY; return(2); } @@ -488,7 +564,7 @@ static UINT midiwrite(COMMNG self, UINT8 break; } keydisp_midi(midi->buffer); - midi->outfn(midi, MIDIOUTS3(midi->buffer)); + midi->shortout(midi, MIDIOUTS3(midi->buffer)); midi->midictrl = MIDICTRL_READY; return(3); } @@ -496,15 +572,7 @@ static UINT midiwrite(COMMNG self, UINT8 case MIDICTRL_EXCLUSIVE: if (data == MIDI_EOX) { - if (midi->opened & CMMIDI_MIDIOUT) { - waitlastexclusiveout(midi); - sendexclusive(midi, midi->buffer, midi->mpos); - } -#if defined(VERMOUTH_LIB) - else if (midi->opened & CMMIDI_VERMOUTH) { - midiout_longmsg(midi->vermouth, midi->buffer, midi->mpos); - } -#endif + midi->longout(midi, midi->buffer, midi->mpos); midi->midictrl = MIDICTRL_READY; return(midi->mpos); } @@ -587,7 +655,7 @@ static long midimsg(COMMNG self, UINT ms return(0); } -static BOOL midiinhdlreg(CMMIDI midi, HMIDIIN hmidiin) { +static BRESULT midiinhdlreg(CMMIDI midi, HMIDIIN hmidiin) { if (midiinhdls < MIDIIN_MAX) { midiinhdl[midiinhdls].hmidiin = hmidiin; @@ -635,10 +703,11 @@ static void midirelease(COMMNG self) { CMMIDI midi; midi = (CMMIDI)(self + 1); + midiallnoteoff(midi); if (midi->opened & CMMIDI_MIDIOUT) { waitlastexclusiveout(midi); - midiOutReset(midi->hmidiout); - midiOutClose(midi->hmidiout); + midiOutReset(midi->out.win32.hmidiout); + midiOutClose(midi->out.win32.hmidiout); } if (midi->opened & CMMIDI_MIDIIN) { if (midi->opened & CMMIDI_MIDIINSTART) { @@ -652,7 +721,12 @@ static void midirelease(COMMNG self) { } #if defined(VERMOUTH_LIB) if (midi->opened & CMMIDI_VERMOUTH) { - midiout_destroy(midi->vermouth); + midiout_destroy(midi->out.vermouth); + } +#endif +#if defined(MT32SOUND_DLL) + if (midi->opened & CMMIDI_MT32SOUND) { + mt32sound_close(); } #endif _MFREE(self); @@ -677,27 +751,28 @@ COMMNG cmmidi_create(const OEMCHAR *midi UINT opened; UINT id; - void (*outfn)(CMMIDI midi, UINT32 msg); - HMIDIOUT hmidiout = NULL; + void (*shortout)(CMMIDI self, UINT32 msg); + void (*longout)(CMMIDI self, const UINT8 *msg, UINT leng); + HMIDIFNOUT out; HMIDIIN hmidiin = NULL; -#if defined(VERMOUTH_LIB) - MIDIHDL vermouth = NULL; -#endif COMMNG ret; CMMIDI midi; opened = 0; - outfn = midiout_none; + ZeroMemory(&out, sizeof(out)); + shortout = midi_ncshort; + longout = midi_nclong; if (getmidioutid(midiout, &id) == SUCCESS) { - if (midiOutOpen(&hmidiout, id, 0, 0, CALLBACK_NULL) + if (midiOutOpen(&out.win32.hmidiout, id, 0, 0, CALLBACK_NULL) == MMSYSERR_NOERROR) { - midiOutReset(hmidiout); - outfn = midiout_win32; + midiOutReset(out.win32.hmidiout); + shortout = midi_win32short; + longout = midi_win32long; opened |= CMMIDI_MIDIOUT; } } if (getmidiinid(midiin, &id) == SUCCESS) { - if (midiInOpen(&hmidiin, id, (DWORD)hWndMain, 0, CALLBACK_WINDOW) + if (midiInOpen(&hmidiin, id, (DWORD)g_hWndMain, 0, CALLBACK_WINDOW) == MMSYSERR_NOERROR) { midiInReset(hmidiin); opened |= CMMIDI_MIDIIN; @@ -705,13 +780,23 @@ COMMNG cmmidi_create(const OEMCHAR *midi } #if defined(VERMOUTH_LIB) else if (!milstr_cmp(midiout, cmmidi_vermouth)) { - vermouth = midiout_create(vermouth_module, 512); - if (vermouth != NULL) { - outfn = midiout_vermouth; + out.vermouth = midiout_create(vermouth_module, 512); + if (out.vermouth != NULL) { + shortout = midi_vermouthshort; + longout = midi_vermouthlong; opened |= CMMIDI_VERMOUTH; } } #endif +#if defined(MT32SOUND_DLL) + else if (!milstr_cmp(midiout, cmmidi_mt32sound)) { + if (mt32sound_open() == SUCCESS) { + shortout = midi_mt32short; + longout = midi_mt32long; + opened |= CMMIDI_MT32SOUND; + } + } +#endif if (!opened) { goto cmcre_err1; } @@ -728,9 +813,10 @@ COMMNG cmmidi_create(const OEMCHAR *midi midi = (CMMIDI)(ret + 1); ZeroMemory(midi, sizeof(_CMMIDI)); midi->opened = opened; - midi->outfn = outfn; + midi->shortout = shortout; + midi->longout = longout; + midi->out = out; midi->midictrl = MIDICTRL_READY; - midi->hmidiout = hmidiout; #if 1 midi->hmidiin = hmidiin; if (opened & CMMIDI_MIDIIN) { @@ -745,9 +831,13 @@ COMMNG cmmidi_create(const OEMCHAR *midi } #endif #if defined(VERMOUTH_LIB) - midi->vermouth = vermouth; if (opened & CMMIDI_VERMOUTH) { - sound_streamregist((void *)vermouth, (SOUNDCB)vermouth_getpcm); + sound_streamregist((void *)out.vermouth, (SOUNDCB)vermouth_getpcm); + } +#endif +#if defined(MT32SOUND_DLL) + if (opened & CMMIDI_MT32SOUND) { + sound_streamregist(NULL, (SOUNDCB)mt32_getpcm); } #endif // midi->midisyscnt = 0; @@ -761,12 +851,17 @@ COMMNG cmmidi_create(const OEMCHAR *midi cmcre_err2: if (opened & CMMIDI_MIDIOUT) { - midiOutReset(hmidiout); - midiOutClose(hmidiout); + midiOutReset(out.win32.hmidiout); + midiOutClose(out.win32.hmidiout); } #if defined(VERMOUTH_LIB) if (opened & CMMIDI_VERMOUTH) { - midiout_destroy(vermouth); + midiout_destroy(out.vermouth); + } +#endif +#if defined(MT32SOUND_DLL) + if (opened & CMMIDI_MT32SOUND) { + mt32sound_close(); } #endif