--- np2/win9x/cmmidi.cpp 2003/10/16 17:58:45 1.1 +++ np2/win9x/cmmidi.cpp 2006/12/23 09:48:11 1.10 @@ -2,11 +2,16 @@ #include "np2.h" #include "mimpidef.h" #include "commng.h" -#include "keydisp.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" #if defined(VERMOUTH_LIB) @@ -19,37 +24,42 @@ extern MIDIMOD vermouth_module; #define MIDIOUTS3(a) ((*(UINT32 *)(a)) & 0xffffff) -const char cmmidi_midimapper[] = "MIDI MAPPER"; +const OEMCHAR cmmidi_midimapper[] = OEMTEXT("MIDI MAPPER"); #if defined(VERMOUTH_LIB) -const char cmmidi_vermouth[] = "VERMOUTH"; +const OEMCHAR cmmidi_vermouth[] = OEMTEXT("VERMOUTH"); +#endif +#if defined(MT32SOUND_DLL) +const OEMCHAR cmmidi_mt32sound[] = OEMTEXT("MT32Sound"); #endif -const char *cmmidi_mdlname[12] = { - "MT-32", "CM-32L", "CM-64", - "CM-300", "CM-500(LA)", "CM-500(GS)", - "SC-55", "SC-88", "LA", - "GM", "GS", "XG"}; + +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)"), + OEMTEXT("SC-55"), OEMTEXT("SC-88"), OEMTEXT("LA"), + OEMTEXT("GM"), OEMTEXT("GS"), OEMTEXT("XG")}; enum { MIDI_MT32 = 0, MIDI_CM32L, MIDI_CM64, MIDI_CM300, MIDI_CM500LA, MIDI_CM500GS, MIDI_SC55, MIDI_SC88, MIDI_LA, MIDI_GM, MIDI_GS, MIDI_XG, MIDI_OTHER}; -static const BYTE EXCV_MTRESET[] = { - 0xfe, 0xfe, 0xfe}; -static const BYTE EXCV_GMRESET[] = { - 0xf0, 0x7e, 0x7f, 0x09, 0x01, 0xf7}; -static const BYTE EXCV_GSRESET[] = { - 0xf0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7f, 0x00, 0x41, 0xf7}; -static const BYTE EXCV_XGRESET[] = { - 0xf0, 0x43, 0x10, 0x4C, 0x00, 0x00, 0x7E, 0x00, 0xf7}; -static const BYTE EXCV_GMVOLUME[] = { - 0xf0, 0x7F, 0x7F, 0x04, 0x01, 0x00, 0x00, 0xF7}; +static const UINT8 EXCV_MTRESET[] = { + 0xf0,0x41,0x10,0x16,0x12,0x7f,0x00,0x00,0x00,0x01,0xf7}; +static const UINT8 EXCV_GMRESET[] = { + 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}; +static const UINT8 EXCV_XGRESET[] = { + 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, @@ -83,35 +96,52 @@ struct _cmmidi; typedef struct _cmmidi _CMMIDI; typedef struct _cmmidi *CMMIDI; -struct _cmmidi { - UINT opened; - void (*outfn)(CMMIDI self, UINT32 msg); +typedef struct { + UINT8 prog; + UINT8 press; + UINT16 bend; + UINT8 ctrl[28]; +} _MIDICH, *MIDICH; + +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; UINT midisyscnt; UINT mpos; - BYTE midilast; - BYTE midiexcvwait; - BYTE midimodule; + UINT8 midilast; + UINT8 midiexcvwait; + UINT8 midimodule; - BYTE buffer[MIDI_BUFFER]; + UINT8 buffer[MIDI_BUFFER]; _MIDICH mch[16]; - BYTE excvbuf[MIDI_BUFFER]; + UINT8 excvbuf[MIDI_BUFFER]; - BYTE def_en; + UINT8 def_en; MIMPIDEF def; UINT recvpos; UINT recvsize; - BYTE recvbuf[MIDI_BUFFER]; - BYTE midiinbuf[MIDI_BUFFER]; + UINT8 recvbuf[MIDI_BUFFER]; + UINT8 midiinbuf[MIDI_BUFFER]; }; typedef struct { @@ -122,17 +152,17 @@ typedef struct { static UINT midiinhdls; static MIDIINHDL midiinhdl[MIDIIN_MAX]; -static const BYTE midictrltbl[] = { 0, 1, 5, 7, 10, 11, 64, +static const UINT8 midictrltbl[] = { 0, 1, 5, 7, 10, 11, 64, 65, 66, 67, 84, 91, 93, 94, // for SC-88 71, 72, 73, 74}; // for XG -static BYTE midictrlindex[128]; +static UINT8 midictrlindex[128]; // ---- -static BOOL getmidioutid(const char *midiout, UINT *ret) { +static BRESULT getmidioutid(const OEMCHAR *midiout, UINT *ret) { UINT num; UINT i; @@ -153,7 +183,7 @@ static BOOL getmidioutid(const char *mid return(FAILURE); } -static BOOL getmidiinid(const char *midiin, UINT *ret) { +static BRESULT getmidiinid(const OEMCHAR *midiin, UINT *ret) { UINT num; UINT i; @@ -174,55 +204,82 @@ static BOOL getmidiinid(const char *midi return(FAILURE); } -static UINT module2number(const char *module) { +static UINT module2number(const OEMCHAR *module) { UINT i; - for (i=0; i<(sizeof(cmmidi_mdlname)/sizeof(char *)); i++) { - if (milstr_extendcmp(module, cmmidi_mdlname[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 BYTE *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) { @@ -247,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 BYTE *excv; +const UINT8 *excv; UINT excvsize; - BYTE work[4]; switch(midi->midimodule) { case MIDI_GM: @@ -288,47 +384,33 @@ const BYTE *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) { - BYTE i; + UINT8 i; UINT j; MIDICH mch; 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)); } } } @@ -336,7 +418,7 @@ static void midisetparam(CMMIDI midi) { // ---- -static UINT midiread(COMMNG self, BYTE *data) { +static UINT midiread(COMMNG self, UINT8 *data) { CMMIDI midi; @@ -350,7 +432,7 @@ static UINT midiread(COMMNG self, BYTE * return(0); } -static UINT midiwrite(COMMNG self, BYTE data) { +static UINT midiwrite(COMMNG self, UINT8 data) { CMMIDI midi; MIDICH mch; @@ -404,11 +486,12 @@ static UINT midiwrite(COMMNG self, BYTE 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); @@ -448,7 +531,7 @@ static UINT midiwrite(COMMNG self, BYTE break; } keydisp_midi(midi->buffer); - midi->outfn(midi, MIDIOUTS2(midi->buffer)); + midi->shortout(midi, MIDIOUTS2(midi->buffer)); midi->midictrl = MIDICTRL_READY; return(2); } @@ -463,12 +546,12 @@ static UINT midiwrite(COMMNG self, BYTE if (midi->buffer[1] == 123) { mch->press = 0; mch->bend = 0x4000; - mch->ctrl[1] = 0; // Modulation - mch->ctrl[5] = 127; // Explession - mch->ctrl[6] = 0; // Hold - mch->ctrl[7] = 0; // Portament - mch->ctrl[8] = 0; // Sostenute - mch->ctrl[9] = 0; // Soft + mch->ctrl[1+1] = 0; // Modulation + mch->ctrl[5+1] = 127; // Explession + mch->ctrl[6+1] = 0; // Hold + mch->ctrl[7+1] = 0; // Portament + mch->ctrl[8+1] = 0; // Sostenute + mch->ctrl[9+1] = 0; // Soft } else { mch->ctrl[midictrlindex[midi->buffer[1]]] @@ -481,7 +564,7 @@ static UINT midiwrite(COMMNG self, BYTE break; } keydisp_midi(midi->buffer); - midi->outfn(midi, MIDIOUTS3(midi->buffer)); + midi->shortout(midi, MIDIOUTS3(midi->buffer)); midi->midictrl = MIDICTRL_READY; return(3); } @@ -489,15 +572,7 @@ static UINT midiwrite(COMMNG self, BYTE 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); } @@ -529,14 +604,15 @@ static UINT midiwrite(COMMNG self, BYTE return(0); } -static BYTE midigetstat(COMMNG self) { +static UINT8 midigetstat(COMMNG self) { return(0x00); } -static UINT midimsg(COMMNG self, UINT msg, long param) { +static long midimsg(COMMNG self, UINT msg, long param) { CMMIDI midi; + COMFLAG flag; midi = (CMMIDI)(self + 1); switch(msg) { @@ -544,27 +620,42 @@ static UINT midimsg(COMMNG self, UINT ms midireset(midi); return(1); + case COMMSG_SETFLAG: + flag = (COMFLAG)param; + if ((flag) && + (flag->size == sizeof(_COMFLAG) + sizeof(midi->mch)) && + (flag->sig == COMSIG_MIDI)) { + CopyMemory(midi->mch, flag + 1, sizeof(midi->mch)); + midisetparam(midi); + return(1); + } + break; + + case COMMSG_GETFLAG: + flag = (COMFLAG)_MALLOC(sizeof(_COMFLAG) + sizeof(midi->mch), + "MIDI FLAG"); + if (flag) { + flag->size = sizeof(_COMFLAG) + sizeof(midi->mch); + flag->sig = COMSIG_MIDI; + flag->ver = 0; + flag->param = 0; + CopyMemory(flag + 1, midi->mch, sizeof(midi->mch)); + return((long)flag); + } + break; + case COMMSG_MIMPIDEFFILE: - mimpidef_load(&midi->def, (char *)param); + mimpidef_load(&midi->def, (OEMCHAR *)param); return(1); case COMMSG_MIMPIDEFEN: midi->def_en = (param)?TRUE:FALSE; return(1); - - case COMMSG_MIDISTATSET: - CopyMemory(midi->mch, (void *)param, sizeof(midi->mch)); - midisetparam(midi); - return(1); - - case COMMSG_MIDISTATGET: - CopyMemory((void *)param, midi->mch, sizeof(midi->mch)); - return(1); } return(0); } -static BOOL midiinhdlreg(CMMIDI midi, HMIDIIN hmidiin) { +static BRESULT midiinhdlreg(CMMIDI midi, HMIDIIN hmidiin) { if (midiinhdls < MIDIIN_MAX) { midiinhdl[midiinhdls].hmidiin = hmidiin; @@ -612,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) { @@ -629,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); @@ -643,33 +740,34 @@ void cmmidi_initailize(void) { UINT i; ZeroMemory(midictrlindex, sizeof(midictrlindex)); - for (i=0; iopened = 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) { @@ -722,9 +831,13 @@ COMMNG cmmidi_create(const char *midiout } #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; @@ -732,18 +845,23 @@ COMMNG cmmidi_create(const char *midiout midi->midilast = 0x80; // midi->midiexcvwait = 0; - midi->midimodule = (BYTE)module2number(module); + midi->midimodule = (UINT8)module2number(module); FillMemory(midi->mch, sizeof(midi->mch), 0xff); return(ret); 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 @@ -754,7 +872,7 @@ cmcre_err1: // ---- midiin callback -static void midiinrecv(CMMIDI midi, const BYTE *data, UINT size) { +static void midiinrecv(CMMIDI midi, const UINT8 *data, UINT size) { UINT wpos; UINT wsize; @@ -808,7 +926,7 @@ void cmmidi_recvdata(HMIDIIN hdr, UINT32 break; #endif } - midiinrecv(midi, (BYTE *)&data, databytes); + midiinrecv(midi, (UINT8 *)&data, databytes); } } @@ -818,7 +936,7 @@ void cmmidi_recvexcv(HMIDIIN hdr, MIDIHD midi = midiinhdlget(hdr); if (midi) { - midiinrecv(midi, (BYTE *)data->lpData, data->dwBytesRecorded); + midiinrecv(midi, (UINT8 *)data->lpData, data->dwBytesRecorded); midiInUnprepareHeader(midi->hmidiin, &midi->hmidiinhdr, sizeof(MIDIHDR)); midiInPrepareHeader(midi->hmidiin,