| version 1.2, 2003/10/21 11:22:05 | version 1.10, 2006/12/23 09:48:11 | 
| Line 2 | Line 2 | 
 | #include        "np2.h" | #include        "np2.h" | 
 | #include        "mimpidef.h" | #include        "mimpidef.h" | 
 | #include        "commng.h" | #include        "commng.h" | 
| #if defined(VERMOUTH_LIB) | #if defined(VERMOUTH_LIB) || defined(MT32SOUND_DLL) | 
 | #include        "sound.h" | #include        "sound.h" | 
 |  | #endif | 
 |  | #if defined(VERMOUTH_LIB) | 
 | #include        "vermouth.h" | #include        "vermouth.h" | 
 | #endif | #endif | 
 |  | #if defined(MT32SOUND_DLL) | 
 |  | #include        "mt32snd.h" | 
 |  | #endif | 
 | #include        "keydisp.h" | #include        "keydisp.h" | 
 |  |  | 
 |  |  | 
| Line 19  extern MIDIMOD vermouth_module; | Line 24  extern MIDIMOD vermouth_module; | 
 | #define MIDIOUTS3(a)            ((*(UINT32 *)(a)) & 0xffffff) | #define MIDIOUTS3(a)            ((*(UINT32 *)(a)) & 0xffffff) | 
 |  |  | 
 |  |  | 
| const char cmmidi_midimapper[] = "MIDI MAPPER"; | const OEMCHAR cmmidi_midimapper[] = OEMTEXT("MIDI MAPPER"); | 
 | #if defined(VERMOUTH_LIB) | #if defined(VERMOUTH_LIB) | 
| const char cmmidi_vermouth[] = "VERMOUTH"; | const OEMCHAR cmmidi_vermouth[] = OEMTEXT("VERMOUTH"); | 
 | #endif | #endif | 
| const char *cmmidi_mdlname[12] = { | #if defined(MT32SOUND_DLL) | 
| "MT-32",                "CM-32L",               "CM-64", | const OEMCHAR cmmidi_mt32sound[] = OEMTEXT("MT32Sound"); | 
| "CM-300",               "CM-500(LA)",   "CM-500(GS)", | #endif | 
| "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, | enum {          MIDI_MT32 = 0,  MIDI_CM32L,             MIDI_CM64, | 
 | MIDI_CM300,             MIDI_CM500LA,   MIDI_CM500GS, | MIDI_CM300,             MIDI_CM500LA,   MIDI_CM500GS, | 
 | MIDI_SC55,              MIDI_SC88,              MIDI_LA, | MIDI_SC55,              MIDI_SC88,              MIDI_LA, | 
 | MIDI_GM,                MIDI_GS,                MIDI_XG,        MIDI_OTHER}; | MIDI_GM,                MIDI_GS,                MIDI_XG,        MIDI_OTHER}; | 
 |  |  | 
| static const BYTE EXCV_MTRESET[] = { | static const UINT8 EXCV_MTRESET[] = { | 
| 0xfe, 0xfe, 0xfe}; | 0xf0,0x41,0x10,0x16,0x12,0x7f,0x00,0x00,0x00,0x01,0xf7}; | 
| static const BYTE EXCV_GMRESET[] = { | static const UINT8 EXCV_GMRESET[] = { | 
| 0xf0, 0x7e, 0x7f, 0x09, 0x01, 0xf7}; | 0xf0,0x7e,0x7f,0x09,0x01,0xf7}; | 
| static const BYTE EXCV_GSRESET[] = { | static const UINT8 EXCV_GM2RESET[] = { | 
| 0xf0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7f, 0x00, 0x41, 0xf7}; | 0xf0,0x7e,0x7f,0x09,0x03,0xf7}; | 
| static const BYTE EXCV_XGRESET[] = { | static const UINT8 EXCV_GSRESET[] = { | 
| 0xf0, 0x43, 0x10, 0x4C, 0x00, 0x00, 0x7E, 0x00, 0xf7}; | 0xf0,0x41,0x10,0x42,0x12,0x40,0x00,0x7f,0x00,0x41,0xf7}; | 
| static const BYTE EXCV_GMVOLUME[] = { | static const UINT8 EXCV_XGRESET[] = { | 
| 0xf0, 0x7F, 0x7F, 0x04, 0x01, 0x00, 0x00, 0xF7}; | 0xf0,0x43,0x10,0x4c,0x00,0x00,0x7e,0x00,0xf7}; | 
 |  |  | 
 | enum { | enum { | 
 | MIDI_EXCLUSIVE          = 0xf0, | MIDI_EXCLUSIVE          = 0xf0, | 
 | MIDI_TIMECODE           = 0xf1, | MIDI_TIMECODE           = 0xf1, | 
 | MIDI_SONGPOS            = 0xf2, | MIDI_SONGPOS            = 0xf2, | 
 | MIDI_SONGSELECT         = 0xf3, | MIDI_SONGSELECT         = 0xf3, | 
 |  | MIDI_CABLESELECT        = 0xf5, | 
 | MIDI_TUNEREQUEST        = 0xf6, | MIDI_TUNEREQUEST        = 0xf6, | 
 | MIDI_EOX                        = 0xf7, | MIDI_EOX                        = 0xf7, | 
 | MIDI_TIMING                     = 0xf8, | MIDI_TIMING                     = 0xf8, | 
| Line 70  enum { | Line 80  enum { | 
 | #if defined(VERMOUTH_LIB) | #if defined(VERMOUTH_LIB) | 
 | CMMIDI_VERMOUTH         = 0x08, | CMMIDI_VERMOUTH         = 0x08, | 
 | #endif | #endif | 
 |  | #if defined(MT32SOUND_DLL) | 
 |  | CMMIDI_MT32SOUND        = 0x10, | 
 |  | #endif | 
 |  |  | 
 | MIDICTRL_READY          = 0, | MIDICTRL_READY          = 0, | 
 | MIDICTRL_2BYTES, | MIDICTRL_2BYTES, | 
| Line 83  struct _cmmidi; | Line 96  struct _cmmidi; | 
 | typedef struct _cmmidi  _CMMIDI; | typedef struct _cmmidi  _CMMIDI; | 
 | typedef struct _cmmidi  *CMMIDI; | typedef struct _cmmidi  *CMMIDI; | 
 |  |  | 
| struct _cmmidi { | typedef struct { | 
| UINT            opened; | UINT8   prog; | 
| void            (*outfn)(CMMIDI self, UINT32 msg); | UINT8   press; | 
|  | UINT16  bend; | 
|  | UINT8   ctrl[28]; | 
|  | } _MIDICH, *MIDICH; | 
|  |  | 
|  | typedef struct { | 
 | HMIDIOUT        hmidiout; | HMIDIOUT        hmidiout; | 
| MIDIHDR         hmidiouthdr; | MIDIHDR         midihdr; | 
|  | } OUTFNWIN32; | 
|  |  | 
|  | typedef union { | 
|  | OUTFNWIN32      win32; | 
 | #if defined(VERMOUTH_LIB) | #if defined(VERMOUTH_LIB) | 
 | MIDIHDL         vermouth; | MIDIHDL         vermouth; | 
 | #endif | #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; | HMIDIIN         hmidiin; | 
 | MIDIHDR         hmidiinhdr; | MIDIHDR         hmidiinhdr; | 
 | UINT            midictrl; | UINT            midictrl; | 
 | UINT            midisyscnt; | UINT            midisyscnt; | 
 | UINT            mpos; | UINT            mpos; | 
 |  |  | 
| BYTE            midilast; | UINT8           midilast; | 
| BYTE            midiexcvwait; | UINT8           midiexcvwait; | 
| BYTE            midimodule; | UINT8           midimodule; | 
 |  |  | 
| BYTE            buffer[MIDI_BUFFER]; | UINT8           buffer[MIDI_BUFFER]; | 
 | _MIDICH         mch[16]; | _MIDICH         mch[16]; | 
| BYTE            excvbuf[MIDI_BUFFER]; | UINT8           excvbuf[MIDI_BUFFER]; | 
 |  |  | 
| BYTE            def_en; | UINT8           def_en; | 
 | MIMPIDEF        def; | MIMPIDEF        def; | 
 |  |  | 
 | UINT            recvpos; | UINT            recvpos; | 
 | UINT            recvsize; | UINT            recvsize; | 
| BYTE            recvbuf[MIDI_BUFFER]; | UINT8           recvbuf[MIDI_BUFFER]; | 
| BYTE            midiinbuf[MIDI_BUFFER]; | UINT8           midiinbuf[MIDI_BUFFER]; | 
 | }; | }; | 
 |  |  | 
 | typedef struct { | typedef struct { | 
| Line 122  typedef struct { | Line 152  typedef struct { | 
 | static  UINT            midiinhdls; | static  UINT            midiinhdls; | 
 | static  MIDIINHDL       midiinhdl[MIDIIN_MAX]; | 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, | 65, 66, 67, 84, 91, 93, | 
 | 94,                                             // for SC-88 | 94,                                             // for SC-88 | 
 | 71, 72, 73, 74};                // for XG | 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            num; | 
 | UINT            i; | UINT            i; | 
| Line 153  static BOOL getmidioutid(const char *mid | Line 183  static BOOL getmidioutid(const char *mid | 
 | return(FAILURE); | return(FAILURE); | 
 | } | } | 
 |  |  | 
| static BOOL getmidiinid(const char *midiin, UINT *ret) { | static BRESULT getmidiinid(const OEMCHAR *midiin, UINT *ret) { | 
 |  |  | 
 | UINT            num; | UINT            num; | 
 | UINT            i; | UINT            i; | 
| Line 174  static BOOL getmidiinid(const char *midi | Line 204  static BOOL getmidiinid(const char *midi | 
 | return(FAILURE); | return(FAILURE); | 
 | } | } | 
 |  |  | 
| static UINT module2number(const char *module) { | static UINT module2number(const OEMCHAR *module) { | 
 |  |  | 
 | UINT    i; | UINT    i; | 
 |  |  | 
| for (i=0; i<(sizeof(cmmidi_mdlname)/sizeof(char *)); i++) { | for (i=0; i<NELEMENTS(cmmidi_mdlname); i++) { | 
| if (milstr_extendcmp(module, cmmidi_mdlname[i])) { | if (!milstr_extendcmp(module, cmmidi_mdlname[i])) { | 
 | break; | break; | 
 | } | } | 
 | } | } | 
 | return(i); | return(i); | 
 | } | } | 
 |  |  | 
 |  |  | 
 |  | // ---- N/C | 
 |  |  | 
 |  | static void midi_ncshort(CMMIDI midi, UINT32 msg) { | 
 |  |  | 
 |  | (void)midi; | 
 |  | (void)msg; | 
 |  | } | 
 |  |  | 
 |  | static void midi_nclong(CMMIDI midi, const UINT8 *msg, UINT leng) { | 
 |  |  | 
 |  | (void)midi; | 
 |  | (void)msg; | 
 |  | (void)leng; | 
 |  | } | 
 |  |  | 
 |  |  | 
 |  | // ---- Win32 API | 
 |  |  | 
 | static void waitlastexclusiveout(CMMIDI midi) { | static void waitlastexclusiveout(CMMIDI midi) { | 
 |  |  | 
 | if (midi->midiexcvwait) { | if (midi->midiexcvwait) { | 
 | midi->midiexcvwait = 0; | midi->midiexcvwait = 0; | 
| while(midiOutUnprepareHeader(midi->hmidiout, &midi->hmidiouthdr, | while(midiOutUnprepareHeader(midi->out.win32.hmidiout, | 
| sizeof(MIDIHDR)) == MIDIERR_STILLPLAYING); | &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); | waitlastexclusiveout(midi); | 
| midi->hmidiouthdr.lpData = (char *)midi->excvbuf; | midiOutShortMsg(midi->out.win32.hmidiout, (DWORD)msg); | 
| 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; |  | 
 | } | } | 
 |  |  | 
| static void midiout_none(CMMIDI midi, UINT32 msg) { | static void midi_win32long(CMMIDI midi, const UINT8 *msg, UINT leng) { | 
 |  |  | 
| (void)midi; | waitlastexclusiveout(midi); | 
| (void)msg; | 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); | // ---- Vermouth | 
| midiOutShortMsg(midi->hmidiout, (DWORD)msg); |  | 
| } |  | 
 |  |  | 
 | #if defined(VERMOUTH_LIB) | #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(); | 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) { | static void SOUNDCALL vermouth_getpcm(MIDIHDL hdl, SINT32 *pcm, UINT count) { | 
| Line 247  const SINT32 *ptr; | Line 304  const SINT32 *ptr; | 
 | } | } | 
 | #endif | #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) { | static void midireset(CMMIDI midi) { | 
 |  |  | 
| const BYTE      *excv; | const UINT8     *excv; | 
 | UINT    excvsize; | UINT    excvsize; | 
 | BYTE    work[4]; |  | 
 |  |  | 
 | switch(midi->midimodule) { | switch(midi->midimodule) { | 
 | case MIDI_GM: | case MIDI_GM: | 
| Line 288  const BYTE *excv; | Line 384  const BYTE *excv; | 
 | break; | break; | 
 | } | } | 
 | if (excv) { | if (excv) { | 
| if (midi->opened & CMMIDI_MIDIOUT) { | midi->longout(midi, excv, excvsize); | 
| 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)); |  | 
 | } | } | 
 |  | midiallnoteoff(midi); | 
 | } | } | 
 |  |  | 
 | static void midisetparam(CMMIDI midi) { | static void midisetparam(CMMIDI midi) { | 
 |  |  | 
| BYTE    i; | UINT8   i; | 
 | UINT    j; | UINT    j; | 
 | MIDICH  mch; | MIDICH  mch; | 
 |  |  | 
 | mch = midi->mch; | mch = midi->mch; | 
 | for (i=0; i<16; i++, mch++) { | for (i=0; i<16; i++, mch++) { | 
 | if (mch->press != 0xff) { | 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) { | if (mch->bend != 0xffff) { | 
| midi->outfn(midi, (mch->bend << 8) + 0xe0+i); | midi->shortout(midi, (mch->bend << 8) + 0xe0+i); | 
 | } | } | 
| for (j=0; j<sizeof(midictrltbl)/sizeof(BYTE); j++) { | for (j=0; j<NELEMENTS(midictrltbl); j++) { | 
 | if (mch->ctrl[j+1] != 0xff) { | if (mch->ctrl[j+1] != 0xff) { | 
| midi->outfn(midi, | midi->shortout(midi, | 
 | MIDIOUTS(0xb0+i, midictrltbl[j], mch->ctrl[j+1])); | MIDIOUTS(0xb0+i, midictrltbl[j], mch->ctrl[j+1])); | 
 | } | } | 
 | } | } | 
 | if (mch->prog != 0xff) { | if (mch->prog != 0xff) { | 
| midi->outfn(midi, MIDIOUTS(0xc0+i, mch->prog, 0)); | midi->shortout(midi, MIDIOUTS(0xc0+i, mch->prog, 0)); | 
 | } | } | 
 | } | } | 
 | } | } | 
| Line 336  static void midisetparam(CMMIDI midi) { | Line 418  static void midisetparam(CMMIDI midi) { | 
 |  |  | 
 | // ---- | // ---- | 
 |  |  | 
| static UINT     midiread(COMMNG self, BYTE *data) { | static UINT midiread(COMMNG self, UINT8 *data) { | 
 |  |  | 
 | CMMIDI  midi; | CMMIDI  midi; | 
 |  |  | 
| Line 350  static UINT midiread(COMMNG self, BYTE * | Line 432  static UINT midiread(COMMNG self, BYTE * | 
 | return(0); | return(0); | 
 | } | } | 
 |  |  | 
| static UINT     midiwrite(COMMNG self, BYTE data) { | static UINT midiwrite(COMMNG self, UINT8 data) { | 
 |  |  | 
 | CMMIDI  midi; | CMMIDI  midi; | 
 | MIDICH  mch; | MIDICH  mch; | 
| Line 404  static UINT midiwrite(COMMNG self, BYTE | Line 486  static UINT midiwrite(COMMNG self, BYTE | 
 | midi->midisyscnt = 2; | midi->midisyscnt = 2; | 
 | break; | break; | 
 |  |  | 
| case MIDI_TUNEREQUEST: | case MIDI_CABLESELECT: | 
 | midi->midictrl = MIDICTRL_SYSTEM; | midi->midictrl = MIDICTRL_SYSTEM; | 
 | midi->midisyscnt = 1; | midi->midisyscnt = 1; | 
 | break; | break; | 
 |  |  | 
 |  | //                                              case MIDI_TUNEREQUEST: | 
 | //                                              case MIDI_EOX: | //                                              case MIDI_EOX: | 
 | default: | default: | 
 | return(1); | return(1); | 
| Line 448  static UINT midiwrite(COMMNG self, BYTE | Line 531  static UINT midiwrite(COMMNG self, BYTE | 
 | break; | break; | 
 | } | } | 
 | keydisp_midi(midi->buffer); | keydisp_midi(midi->buffer); | 
| midi->outfn(midi, MIDIOUTS2(midi->buffer)); | midi->shortout(midi, MIDIOUTS2(midi->buffer)); | 
 | midi->midictrl = MIDICTRL_READY; | midi->midictrl = MIDICTRL_READY; | 
 | return(2); | return(2); | 
 | } | } | 
| Line 463  static UINT midiwrite(COMMNG self, BYTE | Line 546  static UINT midiwrite(COMMNG self, BYTE | 
 | if (midi->buffer[1] == 123) { | if (midi->buffer[1] == 123) { | 
 | mch->press = 0; | mch->press = 0; | 
 | mch->bend = 0x4000; | mch->bend = 0x4000; | 
| mch->ctrl[1] = 0;                       // Modulation | mch->ctrl[1+1] = 0;                     // Modulation | 
| mch->ctrl[5] = 127;                     // Explession | mch->ctrl[5+1] = 127;           // Explession | 
| mch->ctrl[6] = 0;                       // Hold | mch->ctrl[6+1] = 0;                     // Hold | 
| mch->ctrl[7] = 0;                       // Portament | mch->ctrl[7+1] = 0;                     // Portament | 
| mch->ctrl[8] = 0;                       // Sostenute | mch->ctrl[8+1] = 0;                     // Sostenute | 
| mch->ctrl[9] = 0;                       // Soft | mch->ctrl[9+1] = 0;                     // Soft | 
 | } | } | 
 | else { | else { | 
 | mch->ctrl[midictrlindex[midi->buffer[1]]] | mch->ctrl[midictrlindex[midi->buffer[1]]] | 
| Line 481  static UINT midiwrite(COMMNG self, BYTE | Line 564  static UINT midiwrite(COMMNG self, BYTE | 
 | break; | break; | 
 | } | } | 
 | keydisp_midi(midi->buffer); | keydisp_midi(midi->buffer); | 
| midi->outfn(midi, MIDIOUTS3(midi->buffer)); | midi->shortout(midi, MIDIOUTS3(midi->buffer)); | 
 | midi->midictrl = MIDICTRL_READY; | midi->midictrl = MIDICTRL_READY; | 
 | return(3); | return(3); | 
 | } | } | 
| Line 489  static UINT midiwrite(COMMNG self, BYTE | Line 572  static UINT midiwrite(COMMNG self, BYTE | 
 |  |  | 
 | case MIDICTRL_EXCLUSIVE: | case MIDICTRL_EXCLUSIVE: | 
 | if (data == MIDI_EOX) { | if (data == MIDI_EOX) { | 
| if (midi->opened & CMMIDI_MIDIOUT) { | midi->longout(midi, midi->buffer, midi->mpos); | 
| 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->midictrl = MIDICTRL_READY; | midi->midictrl = MIDICTRL_READY; | 
 | return(midi->mpos); | return(midi->mpos); | 
 | } | } | 
| Line 529  static UINT midiwrite(COMMNG self, BYTE | Line 604  static UINT midiwrite(COMMNG self, BYTE | 
 | return(0); | return(0); | 
 | } | } | 
 |  |  | 
| static BYTE     midigetstat(COMMNG self) { | static UINT8 midigetstat(COMMNG self) { | 
 |  |  | 
 | return(0x00); | return(0x00); | 
 | } | } | 
 |  |  | 
| static UINT     midimsg(COMMNG self, UINT msg, long param) { | static long midimsg(COMMNG self, UINT msg, long param) { | 
 |  |  | 
 | CMMIDI  midi; | CMMIDI  midi; | 
 |  | COMFLAG flag; | 
 |  |  | 
 | midi = (CMMIDI)(self + 1); | midi = (CMMIDI)(self + 1); | 
 | switch(msg) { | switch(msg) { | 
| Line 544  static UINT midimsg(COMMNG self, UINT ms | Line 620  static UINT midimsg(COMMNG self, UINT ms | 
 | midireset(midi); | midireset(midi); | 
 | return(1); | 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: | case COMMSG_MIMPIDEFFILE: | 
| mimpidef_load(&midi->def, (char *)param); | mimpidef_load(&midi->def, (OEMCHAR *)param); | 
 | return(1); | return(1); | 
 |  |  | 
 | case COMMSG_MIMPIDEFEN: | case COMMSG_MIMPIDEFEN: | 
 | midi->def_en = (param)?TRUE:FALSE; | midi->def_en = (param)?TRUE:FALSE; | 
 | return(1); | 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); | return(0); | 
 | } | } | 
 |  |  | 
| static BOOL midiinhdlreg(CMMIDI midi, HMIDIIN hmidiin) { | static BRESULT midiinhdlreg(CMMIDI midi, HMIDIIN hmidiin) { | 
 |  |  | 
 | if (midiinhdls < MIDIIN_MAX) { | if (midiinhdls < MIDIIN_MAX) { | 
 | midiinhdl[midiinhdls].hmidiin = hmidiin; | midiinhdl[midiinhdls].hmidiin = hmidiin; | 
| Line 612  static void midirelease(COMMNG self) { | Line 703  static void midirelease(COMMNG self) { | 
 | CMMIDI  midi; | CMMIDI  midi; | 
 |  |  | 
 | midi = (CMMIDI)(self + 1); | midi = (CMMIDI)(self + 1); | 
 |  | midiallnoteoff(midi); | 
 | if (midi->opened & CMMIDI_MIDIOUT) { | if (midi->opened & CMMIDI_MIDIOUT) { | 
 | waitlastexclusiveout(midi); | waitlastexclusiveout(midi); | 
| midiOutReset(midi->hmidiout); | midiOutReset(midi->out.win32.hmidiout); | 
| midiOutClose(midi->hmidiout); | midiOutClose(midi->out.win32.hmidiout); | 
 | } | } | 
 | if (midi->opened & CMMIDI_MIDIIN) { | if (midi->opened & CMMIDI_MIDIIN) { | 
 | if (midi->opened & CMMIDI_MIDIINSTART) { | if (midi->opened & CMMIDI_MIDIINSTART) { | 
| Line 629  static void midirelease(COMMNG self) { | Line 721  static void midirelease(COMMNG self) { | 
 | } | } | 
 | #if defined(VERMOUTH_LIB) | #if defined(VERMOUTH_LIB) | 
 | if (midi->opened & CMMIDI_VERMOUTH) { | 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 | #endif | 
 | _MFREE(self); | _MFREE(self); | 
| Line 643  void cmmidi_initailize(void) { | Line 740  void cmmidi_initailize(void) { | 
 | UINT    i; | UINT    i; | 
 |  |  | 
 | ZeroMemory(midictrlindex, sizeof(midictrlindex)); | ZeroMemory(midictrlindex, sizeof(midictrlindex)); | 
| for (i=0; i<sizeof(midictrltbl)/sizeof(BYTE); i++) { | for (i=0; i<NELEMENTS(midictrltbl); i++) { | 
| midictrlindex[midictrltbl[i]] = (BYTE)(i + 1); | midictrlindex[midictrltbl[i]] = (UINT8)(i + 1); | 
 | } | } | 
 | midictrlindex[32] = 1; | midictrlindex[32] = 1; | 
 | } | } | 
 |  |  | 
| COMMNG cmmidi_create(const char *midiout, const char *midiin, | COMMNG cmmidi_create(const OEMCHAR *midiout, const OEMCHAR *midiin, | 
| const char *module) { | const OEMCHAR *module) { | 
 |  |  | 
 | UINT            opened; | UINT            opened; | 
 | UINT            id; | UINT            id; | 
| void            (*outfn)(CMMIDI midi, UINT32 msg); | void            (*shortout)(CMMIDI self, UINT32 msg); | 
| HMIDIOUT        hmidiout = NULL; | void            (*longout)(CMMIDI self, const UINT8 *msg, UINT leng); | 
|  | HMIDIFNOUT      out; | 
 | HMIDIIN         hmidiin = NULL; | HMIDIIN         hmidiin = NULL; | 
 | #if defined(VERMOUTH_LIB) |  | 
 | MIDIHDL         vermouth = NULL; |  | 
 | #endif |  | 
 | COMMNG          ret; | COMMNG          ret; | 
 | CMMIDI          midi; | CMMIDI          midi; | 
 |  |  | 
 | opened = 0; | opened = 0; | 
| outfn = midiout_none; | ZeroMemory(&out, sizeof(out)); | 
|  | shortout = midi_ncshort; | 
|  | longout = midi_nclong; | 
 | if (getmidioutid(midiout, &id) == SUCCESS) { | 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) { | == MMSYSERR_NOERROR) { | 
| midiOutReset(hmidiout); | midiOutReset(out.win32.hmidiout); | 
| outfn = midiout_win32; | shortout = midi_win32short; | 
|  | longout = midi_win32long; | 
 | opened |= CMMIDI_MIDIOUT; | opened |= CMMIDI_MIDIOUT; | 
 | } | } | 
 | } | } | 
| Line 682  COMMNG cmmidi_create(const char *midiout | Line 780  COMMNG cmmidi_create(const char *midiout | 
 | } | } | 
 | #if defined(VERMOUTH_LIB) | #if defined(VERMOUTH_LIB) | 
 | else if (!milstr_cmp(midiout, cmmidi_vermouth)) { | else if (!milstr_cmp(midiout, cmmidi_vermouth)) { | 
| vermouth = midiout_create(vermouth_module, 512); | out.vermouth = midiout_create(vermouth_module, 512); | 
| if (vermouth != NULL) { | if (out.vermouth != NULL) { | 
| outfn = midiout_vermouth; | shortout = midi_vermouthshort; | 
|  | longout = midi_vermouthlong; | 
 | opened |= CMMIDI_VERMOUTH; | opened |= CMMIDI_VERMOUTH; | 
 | } | } | 
 | } | } | 
 | #endif | #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) { | if (!opened) { | 
 | goto cmcre_err1; | goto cmcre_err1; | 
 | } | } | 
| Line 705  COMMNG cmmidi_create(const char *midiout | Line 813  COMMNG cmmidi_create(const char *midiout | 
 | midi = (CMMIDI)(ret + 1); | midi = (CMMIDI)(ret + 1); | 
 | ZeroMemory(midi, sizeof(_CMMIDI)); | ZeroMemory(midi, sizeof(_CMMIDI)); | 
 | midi->opened = opened; | midi->opened = opened; | 
| midi->outfn = outfn; | midi->shortout = shortout; | 
|  | midi->longout = longout; | 
|  | midi->out = out; | 
 | midi->midictrl = MIDICTRL_READY; | midi->midictrl = MIDICTRL_READY; | 
 | midi->hmidiout = hmidiout; |  | 
 | #if 1 | #if 1 | 
 | midi->hmidiin = hmidiin; | midi->hmidiin = hmidiin; | 
 | if (opened & CMMIDI_MIDIIN) { | if (opened & CMMIDI_MIDIIN) { | 
| Line 722  COMMNG cmmidi_create(const char *midiout | Line 831  COMMNG cmmidi_create(const char *midiout | 
 | } | } | 
 | #endif | #endif | 
 | #if defined(VERMOUTH_LIB) | #if defined(VERMOUTH_LIB) | 
 | midi->vermouth = vermouth; |  | 
 | if (opened & CMMIDI_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 | #endif | 
 | //      midi->midisyscnt = 0; | //      midi->midisyscnt = 0; | 
| Line 732  COMMNG cmmidi_create(const char *midiout | Line 845  COMMNG cmmidi_create(const char *midiout | 
 |  |  | 
 | midi->midilast = 0x80; | midi->midilast = 0x80; | 
 | //      midi->midiexcvwait = 0; | //      midi->midiexcvwait = 0; | 
| midi->midimodule = (BYTE)module2number(module); | midi->midimodule = (UINT8)module2number(module); | 
 | FillMemory(midi->mch, sizeof(midi->mch), 0xff); | FillMemory(midi->mch, sizeof(midi->mch), 0xff); | 
 | return(ret); | return(ret); | 
 |  |  | 
 | cmcre_err2: | cmcre_err2: | 
 | if (opened & CMMIDI_MIDIOUT) { | if (opened & CMMIDI_MIDIOUT) { | 
| midiOutReset(hmidiout); | midiOutReset(out.win32.hmidiout); | 
| midiOutClose(hmidiout); | midiOutClose(out.win32.hmidiout); | 
 | } | } | 
 | #if defined(VERMOUTH_LIB) | #if defined(VERMOUTH_LIB) | 
 | if (opened & CMMIDI_VERMOUTH) { | if (opened & CMMIDI_VERMOUTH) { | 
| midiout_destroy(vermouth); | midiout_destroy(out.vermouth); | 
|  | } | 
|  | #endif | 
|  | #if defined(MT32SOUND_DLL) | 
|  | if (opened & CMMIDI_MT32SOUND) { | 
|  | mt32sound_close(); | 
 | } | } | 
 | #endif | #endif | 
 |  |  | 
| Line 754  cmcre_err1: | Line 872  cmcre_err1: | 
 |  |  | 
 | // ---- midiin callback | // ---- 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    wpos; | 
 | UINT    wsize; | UINT    wsize; | 
| Line 808  void cmmidi_recvdata(HMIDIIN hdr, UINT32 | Line 926  void cmmidi_recvdata(HMIDIIN hdr, UINT32 | 
 | break; | break; | 
 | #endif | #endif | 
 | } | } | 
| midiinrecv(midi, (BYTE *)&data, databytes); | midiinrecv(midi, (UINT8 *)&data, databytes); | 
 | } | } | 
 | } | } | 
 |  |  | 
| Line 818  void cmmidi_recvexcv(HMIDIIN hdr, MIDIHD | Line 936  void cmmidi_recvexcv(HMIDIIN hdr, MIDIHD | 
 |  |  | 
 | midi = midiinhdlget(hdr); | midi = midiinhdlget(hdr); | 
 | if (midi) { | if (midi) { | 
| midiinrecv(midi, (BYTE *)data->lpData, data->dwBytesRecorded); | midiinrecv(midi, (UINT8 *)data->lpData, data->dwBytesRecorded); | 
 | midiInUnprepareHeader(midi->hmidiin, | midiInUnprepareHeader(midi->hmidiin, | 
 | &midi->hmidiinhdr, sizeof(MIDIHDR)); | &midi->hmidiinhdr, sizeof(MIDIHDR)); | 
 | midiInPrepareHeader(midi->hmidiin, | midiInPrepareHeader(midi->hmidiin, |