|
|
| version 1.5, 2003/12/01 04:01:42 | version 1.12, 2005/03/29 06:50:38 |
|---|---|
| Line 2 | Line 2 |
| #include "midiout.h" | #include "midiout.h" |
| #define MIDIOUT_VERSION 0x104 | #define MIDIOUT_VERSION 0x105 |
| #define MIDIOUT_VERSTRING "VERMOUTH 1.04" | #define MIDIOUT_VERSTRING "VERMOUTH 1.05" |
| static const char vermouthver[] = MIDIOUT_VERSTRING; | static const OEMCHAR vermouthver[] = OEMTEXT(MIDIOUT_VERSTRING); |
| static const int gaintbl[24+1] = | static const int gaintbl[24+1] = |
| { 16, 19, 22, 26, 32, 38, 45, 53, | { 16, 19, 22, 26, 32, 38, 45, 53, |
| Line 22 static void voice_volupdate(VOICE v) { | Line 22 static void voice_volupdate(VOICE v) { |
| int vol; | int vol; |
| ch = v->channel; | ch = v->channel; |
| #if defined(VOLUME_ACURVE) | |
| vol = ch->level * acurve[v->velocity]; | |
| vol >>= 8; | |
| #else | |
| vol = ch->level * v->velocity; | vol = ch->level * v->velocity; |
| vol >>= 7; | vol >>= 7; |
| #endif | |
| vol *= v->sample->volume; | vol *= v->sample->volume; |
| vol >>= (21 - 16); | vol >>= (21 - 16); |
| #if defined(PANPOT_REVA) | |
| switch(v->flag & VOICE_MIXMASK) { | |
| case VOICE_MIXNORMAL: | |
| v->volleft = (vol * revacurve[v->panpot ^ 127]) >> 8; | |
| v->volright = (vol * revacurve[v->panpot]) >> 8; | |
| break; | |
| case VOICE_MIXCENTRE: | |
| v->volleft = (vol * 155) >> 8; | |
| break; | |
| default: | |
| v->volleft = vol; | |
| break; | |
| } | |
| #else | |
| v->volleft = vol; | v->volleft = vol; |
| if ((v->flag & VOICE_MIXMASK) == VOICE_MIXNORMAL) { | if ((v->flag & VOICE_MIXMASK) == VOICE_MIXNORMAL) { |
| if (v->panpot < 64) { | if (v->panpot < 64) { |
| Line 40 static void voice_volupdate(VOICE v) { | Line 61 static void voice_volupdate(VOICE v) { |
| v->volleft = vol; | v->volleft = vol; |
| } | } |
| } | } |
| #endif | |
| } | } |
| static INSTLAYER selectlayer(VOICE v, INSTRUMENT inst) { | static INSTLAYER selectlayer(VOICE v, INSTRUMENT inst) { |
| Line 183 static void voice_on(MIDIHDL midi, CHANN | Line 205 static void voice_on(MIDIHDL midi, CHANN |
| else { | else { |
| panpot = layer->panpot; | panpot = layer->panpot; |
| } | } |
| #if defined(PANPOT_REVA) | |
| if (panpot == 64) { | |
| v->flag = VOICE_MIXCENTRE; | |
| } | |
| else if (panpot < 3) { | |
| v->flag = VOICE_MIXLEFT; | |
| } | |
| else if (panpot >= 126) { | |
| v->flag = VOICE_MIXRIGHT; | |
| } | |
| else { | |
| v->flag = VOICE_MIXNORMAL; | |
| v->panpot = panpot; | |
| } | |
| #else | |
| if ((panpot >= 60) && (panpot < 68)) { | if ((panpot >= 60) && (panpot < 68)) { |
| v->flag = VOICE_MIXCENTRE; | v->flag = VOICE_MIXCENTRE; |
| } | } |
| Line 196 static void voice_on(MIDIHDL midi, CHANN | Line 233 static void voice_on(MIDIHDL midi, CHANN |
| v->flag = VOICE_MIXNORMAL; | v->flag = VOICE_MIXNORMAL; |
| v->panpot = panpot; | v->panpot = panpot; |
| } | } |
| #endif | |
| if (!layer->samprate) { | if (!layer->samprate) { |
| v->flag |= VOICE_FIXPITCH; | v->flag |= VOICE_FIXPITCH; |
| } | } |
| Line 343 static void volumeupdate(MIDIHDL midi, C | Line 381 static void volumeupdate(MIDIHDL midi, C |
| VOICE v; | VOICE v; |
| VOICE vterm; | VOICE vterm; |
| #if defined(VOLUME_ACURVE) | |
| ch->level = (midi->level * acurve[ch->volume] * ch->expression) >> 15; | |
| #else | |
| ch->level = (midi->level * ch->volume * ch->expression) >> 14; | ch->level = (midi->level * ch->volume * ch->expression) >> 14; |
| #endif | |
| v = midi->voice; | v = midi->voice; |
| vterm = v + VOICE_MAX; | vterm = v + VOICE_MAX; |
| do { | do { |
| Line 428 static void ctrlchange(MIDIHDL midi, CHA | Line 470 static void ctrlchange(MIDIHDL midi, CHA |
| val &= 0x7f; | val &= 0x7f; |
| switch(ctrl & 0x7f) { | switch(ctrl & 0x7f) { |
| #if !defined(MIDI_GMONLY) | |
| case CTRL_PGBANK: | case CTRL_PGBANK: |
| #if defined(ENABLE_GSRX) | |
| if (!(ch->gsrx[2] & GSRX2_BANKSELECT)) { | |
| break; | |
| } | |
| #endif | |
| ch->bank = val; | ch->bank = val; |
| break; | break; |
| #endif | |
| case CTRL_DATA_M: | case CTRL_DATA_M: |
| // TRACEOUT(("data: %x %x %x", c->rpn_l, c->rpn_m, val)); | // TRACEOUT(("data: %x %x %x", c->rpn_l, c->rpn_m, val)); |
| Line 610 static void allvolupdate(MIDIHDL midi) { | Line 659 static void allvolupdate(MIDIHDL midi) { |
| } while(v < vterm); | } while(v < vterm); |
| } | } |
| static void allresetmidi(MIDIHDL midi) { | #if defined(ENABLE_GSRX) |
| static void allresetmidi(MIDIHDL midi, BOOL gs) | |
| #else | |
| #define allresetmidi(m, g) _allresetmidi(m) | |
| static void _allresetmidi(MIDIHDL midi) | |
| #endif | |
| { | |
| CHANNEL ch; | CHANNEL ch; |
| CHANNEL chterm; | CHANNEL chterm; |
| UINT flag; | UINT flag; |
| midi->master = 127; | |
| ch = midi->channel; | ch = midi->channel; |
| chterm = ch + 16; | chterm = ch + 16; |
| ZeroMemory(ch, sizeof(_CHANNEL) * 16); | ZeroMemory(ch, sizeof(_CHANNEL) * 16); |
| flag = 0; | flag = 0; |
| do { | do { |
| ch->flag = flag++; | ch->flag = flag++; |
| ch->panpot = 64; | |
| ch->pitchsens = 2; | ch->pitchsens = 2; |
| #if !defined(MIDI_GMONLY) | |
| ch->bank = 0; | ch->bank = 0; |
| #endif | |
| ch->panpot = 64; | |
| progchange(midi, ch, 0); | progchange(midi, ch, 0); |
| resetallcontrollers(ch); | resetallcontrollers(ch); |
| #if defined(ENABLE_GSRX) | |
| ch->keyshift = 0x40; | |
| ch->noterange[0] = 0x00; | |
| ch->noterange[1] = 0x7f; | |
| if (gs) { | |
| ch->gsrx[0] = 0xff; | |
| ch->gsrx[1] = 0xff; | |
| ch->gsrx[2] = 0xff; | |
| } | |
| else { | |
| ch->gsrx[0] = 0x7f; | |
| ch->gsrx[1] = 0xff; | |
| ch->gsrx[2] = 0x02; | |
| } | |
| #endif | |
| ch++; | ch++; |
| } while(ch < chterm); | } while(ch < chterm); |
| allresetvoices(midi); | allresetvoices(midi); |
| Line 636 static void allresetmidi(MIDIHDL midi) { | Line 708 static void allresetmidi(MIDIHDL midi) { |
| // ---- | // ---- |
| UINT midiout_getver(char *string, int leng) { | UINT midiout_getver(OEMCHAR *string, int leng) { |
| milstr_ncpy(string, vermouthver, leng); | milstr_ncpy(string, vermouthver, leng); |
| return((MIDIOUT_VERSION << 8) | 0x00); | return((MIDIOUT_VERSION << 8) | 0x00); |
| Line 661 MIDIHDL midiout_create(MIDIMOD module, U | Line 733 MIDIHDL midiout_create(MIDIMOD module, U |
| ret->samprate = module->samprate; | ret->samprate = module->samprate; |
| ret->worksize = worksize; | ret->worksize = worksize; |
| ret->module = module; | ret->module = module; |
| ret->master = 127; | // ret->master = 127; |
| ret->bank0[0] = module->tone[0]; | ret->bank0[0] = module->tone[0]; |
| ret->bank0[1] = module->tone[1]; | ret->bank0[1] = module->tone[1]; |
| ret->sampbuf = (SINT32 *)(ret + 1); | ret->sampbuf = (SINT32 *)(ret + 1); |
| ret->resampbuf = (SAMPLE)(ret->sampbuf + worksize * 2); | ret->resampbuf = (SAMPLE)(ret->sampbuf + worksize * 2); |
| allresetmidi(ret); | allresetmidi(ret, FALSE); |
| } | } |
| return(ret); | return(ret); |
| } | } |
| Line 731 void midiout_shortmsg(MIDIHDL hdl, UINT3 | Line 803 void midiout_shortmsg(MIDIHDL hdl, UINT3 |
| } | } |
| } | } |
| void midiout_longmsg(MIDIHDL hdl, const BYTE *msg, UINT size) { | static void longmsg_gm(MIDIHDL hdl, const UINT8 *msg, UINT size) { |
| if ((size > 5) && (msg[2] == 0x7f) && (msg[3] == 0x09)) { | |
| allresetmidi(hdl, FALSE); // GM reset | |
| } | |
| } | |
| static void longmsg_roland(MIDIHDL hdl, const UINT8 *msg, UINT size) { | |
| UINT addr; | |
| UINT8 data; | |
| UINT part; | |
| CHANNEL ch; | |
| #if defined(ENABLE_GSRX) | |
| UINT8 bit; | |
| #endif | |
| if (size <= 10) { | |
| return; | |
| } | |
| // GS data set | |
| if ((msg[2] != 0x10) || (msg[3] != 0x42) || (msg[4] != 0x12)) { | |
| return; | |
| } | |
| addr = (msg[5] << 16) + (msg[6] << 8) + msg[7]; | |
| msg += 8; | |
| size -= 10; | |
| while(size) { | |
| size--; | |
| data = (*msg++) & 0x7f; | |
| if ((addr & (~0x400000)) == 0x7f) { // GS reset | |
| allresetmidi(hdl, TRUE); | |
| TRACEOUT(("GS-Reset")); | |
| } | |
| else if (addr == 0x400004) { // Vol | |
| hdl->master = data; | |
| allvolupdate(hdl); | |
| } | |
| else if ((addr & (~(0x000fff))) == 0x401000) { // GS CH | |
| part = (addr >> 8) & 0x0f; | |
| if (part == 0) { // part10 | |
| part = 9; | |
| } | |
| else if (part < 10) { // part1-9 | |
| part--; | |
| } | |
| ch = hdl->channel + part; | |
| switch(addr & 0xff) { | |
| #if !defined(MIDI_GMONLY) | |
| case 0x00: // TONE NUMBER | |
| ch->bank = data; | |
| break; | |
| #endif | |
| case 0x01: // PROGRAM NUMBER | |
| progchange(hdl, ch, data); | |
| break; | |
| #if defined(ENABLE_GSRX) | |
| case 0x03: // Rx.PITCHBEND | |
| case 0x04: // Rx.CH PRESSURE | |
| case 0x05: // Rx.PROGRAM CHANGE | |
| case 0x06: // Rx.CONTROL CHANGE | |
| case 0x07: // Rx.POLY PRESSURE | |
| case 0x08: // Rx.NOTE MESSAGE | |
| case 0x09: // Rx.PRN | |
| case 0x0a: // Rx.NRPN | |
| bit = 1 << ((addr - 0x03) & 7); | |
| if (data == 0) { | |
| ch->gsrx[0] = ch->gsrx[0] & (~bit); | |
| } | |
| else if (data == 1) { | |
| ch->gsrx[0] = ch->gsrx[0] | bit; | |
| } | |
| break; | |
| case 0x0b: // Rx.MODULATION | |
| case 0x0c: // Rx.VOLUME | |
| case 0x0d: // Rx.PANPOT | |
| case 0x0e: // Rx.EXPRESSION | |
| case 0x0f: // Rx.HOLD1 | |
| case 0x10: // Rx.PORTAMENTO | |
| case 0x11: // Rx.SOSTENUTO | |
| case 0x12: // Rx.SOFT | |
| bit = 1 << ((addr - 0x0b) & 7); | |
| if (data == 0) { | |
| ch->gsrx[1] = ch->gsrx[1] & (~bit); | |
| } | |
| else if (data == 1) { | |
| ch->gsrx[1] = ch->gsrx[1] | bit; | |
| } | |
| break; | |
| #endif | |
| case 0x15: // USE FOR RHYTHM PART | |
| if (data == 0) { | |
| ch->flag &= ~CHANNEL_RHYTHM; | |
| TRACEOUT(("ch%d - tone", part + 1)); | |
| } | |
| else if ((data == 1) || (data == 2)) { | |
| ch->flag |= CHANNEL_RHYTHM; | |
| TRACEOUT(("ch%d - rhythm", part + 1)); | |
| } | |
| break; | |
| #if defined(ENABLE_GSRX) | |
| case 0x16: // PITCH KEY SHIFT | |
| if ((data >= 0x28) && (data <= 0x58)) { | |
| ch->keyshift = data; | |
| } | |
| break; | |
| case 0x1d: // KEYBOARD RANGE LOW | |
| ch->noterange[0] = data; | |
| break; | |
| case 0x1e: // KEYBOARD RANGE HIGH | |
| ch->noterange[1] = data; | |
| break; | |
| case 0x23: // Rx.BANK SELECT | |
| case 0x24: // Rx.BANK SELECT LSB | |
| bit = 1 << ((addr - 0x23) & 7); | |
| if (data == 0) { | |
| ch->gsrx[2] = ch->gsrx[2] & (~bit); | |
| } | |
| else if (data == 1) { | |
| ch->gsrx[2] = ch->gsrx[2] | bit; | |
| } | |
| break; | |
| #endif | |
| default: | |
| TRACEOUT(("Roland GS - %.6x", addr)); | |
| break; | |
| } | |
| } | |
| else { | |
| TRACEOUT(("Roland GS - %.6x", addr)); | |
| } | |
| addr++; | |
| } | |
| } | |
| void midiout_longmsg(MIDIHDL hdl, const UINT8 *msg, UINT size) { | |
| UINT id; | |
| if ((hdl == NULL) || (msg == NULL)) { | if ((hdl == NULL) || (msg == NULL)) { |
| return; | return; |
| } | } |
| if ((size > 5) && (msg[1] == 0x7e)) { // GM | if (size > 3) { // (msg[size - 1] == 0xf7) |
| if ((msg[2] == 0x7f) && (msg[3] == 0x09)) { | id = msg[1]; |
| allresetmidi(hdl); // GM reset | if (id == 0x7e) { // GM |
| longmsg_gm(hdl, msg, size); | |
| } | |
| else if (id == 0x41) { // Roland | |
| longmsg_roland(hdl, msg, size); | |
| } | } |
| } | } |
| } | } |