--- np2/sound/vermouth/midiout.c 2006/12/16 09:51:46 1.15 +++ np2/sound/vermouth/midiout.c 2006/12/17 17:53:24 1.18 @@ -2,8 +2,8 @@ #include "midiout.h" -#define MIDIOUT_VERSION 0x115 -#define MIDIOUT_VERSTRING "VERMOUTH 1.15" +#define MIDIOUT_VERSION 0x116 +#define MIDIOUT_VERSTRING "VERMOUTH 1.16" static const char vermouthver[] = MIDIOUT_VERSTRING; @@ -15,7 +15,10 @@ static const int gaintbl[24+1] = // ---- voice -static void voice_volupdate(VOICE v) { +#define VOICEHDLPTR(hdl) ((hdl)->voice) +#define VOICEHDLEND(hdl) (VOICE)((hdl) + 1) + +static void VERMOUTHCL voice_volupdate(VOICE v) { CHANNEL ch; int vol; @@ -63,7 +66,7 @@ static void voice_volupdate(VOICE v) { #endif } -static INSTLAYER selectlayer(VOICE v, INSTRUMENT inst) { +static INSTLAYER VERMOUTHCL selectlayer(VOICE v, INSTRUMENT inst) { int layers; INSTLAYER layer; @@ -110,7 +113,7 @@ static INSTLAYER selectlayer(VOICE v, IN return(layersel); } -static void freq_update(VOICE v) { +static void VERMOUTHCL freq_update(VOICE v) { CHANNEL ch; float step; @@ -134,7 +137,8 @@ static void freq_update(VOICE v) { v->sampstep = (int)step; } -static void voice_on(MIDIHDL midi, CHANNEL ch, VOICE v, int key, int vel) { +static void VERMOUTHCL voice_on(MIDIHDL hdl, CHANNEL ch, VOICE v, int key, + int vel) { INSTRUMENT inst; INSTLAYER layer; @@ -158,10 +162,10 @@ static void voice_on(MIDIHDL midi, CHANN #if !defined(MIDI_GMONLY) inst = ch->rhythm[key]; if (inst == NULL) { - inst = midi->bank0[1][key]; + inst = hdl->bank0[1][key]; } #else - inst = midi->bank0[1][key]; + inst = hdl->bank0[1][key]; #endif if (inst == NULL) { return; @@ -237,7 +241,7 @@ static void voice_on(MIDIHDL midi, CHANN v->flag |= VOICE_FIXPITCH; } else { - v->freq = (float)layer->samprate / (float)midi->samprate * + v->freq = (float)layer->samprate / (float)hdl->samprate * (float)v->frequency / (float)layer->freqroot; } voice_setphase(v, VOICE_ON); @@ -255,7 +259,7 @@ static void voice_on(MIDIHDL midi, CHANN envelope_updates(v); } -static void voice_off(VOICE v) { +static void VERMOUTHCL voice_off(VOICE v) { voice_setphase(v, VOICE_OFF); if (v->sample->mode & MODE_ENVELOPE) { @@ -265,13 +269,13 @@ static void voice_off(VOICE v) { } } -static void allresetvoices(MIDIHDL midi) { +static void VERMOUTHCL allresetvoices(MIDIHDL hdl) { VOICE v; VOICE vterm; - v = midi->voice; - vterm = v + VOICE_MAX; + v = VOICEHDLPTR(hdl); + vterm = VOICEHDLEND(hdl); do { voice_setfree(v); v++; @@ -281,7 +285,7 @@ static void allresetvoices(MIDIHDL midi) // ---- key -static void key_on(MIDIHDL midi, CHANNEL ch, int key, int vel) { +static void VERMOUTHCL key_on(MIDIHDL hdl, CHANNEL ch, int key, int vel) { VOICE v; VOICE v1; @@ -290,8 +294,8 @@ static void key_on(MIDIHDL midi, CHANNEL int volmin; v = NULL; - v1 = midi->voice; - v2 = v1 + VOICE_MAX; + v1 = VOICEHDLPTR(hdl); + v2 = VOICEHDLEND(hdl); do { v2--; if (v2->phase == VOICE_FREE) { @@ -305,12 +309,12 @@ static void key_on(MIDIHDL midi, CHANNEL } while(v1 < v2); if (v != NULL) { - voice_on(midi, ch, v, key, vel); + voice_on(hdl, ch, v, key, vel); return; } volmin = 0x7fffffff; - v2 = v1 + VOICE_MAX; + v2 = VOICEHDLEND(hdl); do { v2--; if (!(v2->phase & (VOICE_ON | VOICE_REL))) { @@ -327,17 +331,17 @@ static void key_on(MIDIHDL midi, CHANNEL if (v != NULL) { voice_setfree(v); - voice_on(midi, ch, v, key, vel); + voice_on(hdl, ch, v, key, vel); } } -static void key_off(MIDIHDL midi, CHANNEL ch, int key) { +static void VERMOUTHCL key_off(MIDIHDL hdl, CHANNEL ch, int key) { VOICE v; VOICE vterm; - v = midi->voice; - vterm = v + VOICE_MAX; + v = VOICEHDLPTR(hdl); + vterm = VOICEHDLEND(hdl); do { if ((v->phase & VOICE_ON) && (v->channel == ch) && (v->note == key)) { @@ -353,13 +357,14 @@ static void key_off(MIDIHDL midi, CHANNE } while(v < vterm); } -static void key_pressure(MIDIHDL midi, CHANNEL ch, int key, int vel) { +static void VERMOUTHCL key_pressure(MIDIHDL hdl, CHANNEL ch, int key, + int vel) { VOICE v; VOICE vterm; - v = midi->voice; - vterm = v + VOICE_MAX; + v = VOICEHDLPTR(hdl); + vterm = VOICEHDLEND(hdl); do { if ((v->phase & VOICE_ON) && (v->channel == ch) && (v->note == key)) { @@ -375,18 +380,18 @@ static void key_pressure(MIDIHDL midi, C // ---- control -static void volumeupdate(MIDIHDL midi, CHANNEL ch) { +static void VERMOUTHCL volumeupdate(MIDIHDL hdl, CHANNEL ch) { VOICE v; VOICE vterm; #if defined(VOLUME_ACURVE) - ch->level = (midi->level * acurve[ch->volume] * ch->expression) >> 15; + ch->level = (hdl->level * acurve[ch->volume] * ch->expression) >> 15; #else - ch->level = (midi->level * ch->volume * ch->expression) >> 14; + ch->level = (hdl->level * ch->volume * ch->expression) >> 14; #endif - v = midi->voice; - vterm = v + VOICE_MAX; + v = VOICEHDLPTR(hdl); + vterm = VOICEHDLEND(hdl); do { if ((v->phase & (VOICE_ON | VOICE_SUSTAIN)) && (v->channel == ch)) { voice_volupdate(v); @@ -396,13 +401,13 @@ static void volumeupdate(MIDIHDL midi, C } while(v < vterm); } -static void pedaloff(MIDIHDL midi, CHANNEL ch) { +static void VERMOUTHCL pedaloff(MIDIHDL hdl, CHANNEL ch) { VOICE v; VOICE vterm; - v = midi->voice; - vterm = v + VOICE_MAX; + v = VOICEHDLPTR(hdl); + vterm = VOICEHDLEND(hdl); do { if ((v->phase & VOICE_SUSTAIN) && (v->channel == ch)) { voice_off(v); @@ -411,13 +416,13 @@ static void pedaloff(MIDIHDL midi, CHANN } while(v < vterm); } -static void allsoundsoff(MIDIHDL midi, CHANNEL ch) { +static void VERMOUTHCL allsoundsoff(MIDIHDL hdl, CHANNEL ch) { VOICE v; VOICE vterm; - v = midi->voice; - vterm = v + VOICE_MAX; + v = VOICEHDLPTR(hdl); + vterm = VOICEHDLEND(hdl); do { if ((v->phase != VOICE_FREE) && (v->channel == ch)) { voice_setphase(v, VOICE_REL); @@ -427,7 +432,7 @@ static void allsoundsoff(MIDIHDL midi, C } while(v < vterm); } -static void resetallcontrollers(CHANNEL ch) { +static void VERMOUTHCL resetallcontrollers(CHANNEL ch) { ch->flag &= CHANNEL_MASK; if (ch->flag == 9) { @@ -439,13 +444,13 @@ static void resetallcontrollers(CHANNEL ch->pitchfactor = 1.0; } -static void allnotesoff(MIDIHDL midi, CHANNEL ch) { +static void VERMOUTHCL allnotesoff(MIDIHDL hdl, CHANNEL ch) { VOICE v; VOICE vterm; - v = midi->voice; - vterm = v + VOICE_MAX; + v = VOICEHDLPTR(hdl); + vterm = VOICEHDLEND(hdl); do { #if 1 if ((v->phase & (VOICE_ON | VOICE_SUSTAIN)) && (v->channel == ch)) { @@ -465,7 +470,8 @@ static void allnotesoff(MIDIHDL midi, CH } while(v < vterm); } -static void ctrlchange(MIDIHDL midi, CHANNEL ch, int ctrl, int val) { +static void VERMOUTHCL ctrlchange(MIDIHDL hdl, CHANNEL ch, int ctrl, + int val) { val &= 0x7f; switch(ctrl & 0x7f) { @@ -492,7 +498,7 @@ static void ctrlchange(MIDIHDL midi, CHA case CTRL_VOLUME: ch->volume = val; - volumeupdate(midi, ch); + volumeupdate(hdl, ch); break; case CTRL_PANPOT: @@ -501,13 +507,13 @@ static void ctrlchange(MIDIHDL midi, CHA case CTRL_EXPRESS: ch->expression = val; - volumeupdate(midi, ch); + volumeupdate(hdl, ch); break; case CTRL_PEDAL: if (val == 0) { ch->flag &= ~CHANNEL_SUSTAIN; - pedaloff(midi, ch); + pedaloff(hdl, ch); } else { ch->flag |= CHANNEL_SUSTAIN; @@ -523,7 +529,7 @@ static void ctrlchange(MIDIHDL midi, CHA break; case CTRL_SOUNDOFF: - allsoundsoff(midi, ch); + allsoundsoff(hdl, ch); break; case CTRL_RESETCTRL: @@ -531,7 +537,7 @@ static void ctrlchange(MIDIHDL midi, CHA /*FALLTHROUGH*/ case CTRL_NOTEOFF: - allnotesoff(midi, ch); + allnotesoff(hdl, ch); break; case CTRL_MONOON: @@ -548,48 +554,48 @@ static void ctrlchange(MIDIHDL midi, CHA } } -static void progchange(MIDIHDL midi, CHANNEL ch, int val) { +static void VERMOUTHCL progchange(MIDIHDL hdl, CHANNEL ch, int val) { #if !defined(MIDI_GMONLY) - MIDIMOD module; + MIDIMOD mod; INSTRUMENT *bank; INSTRUMENT inst; - module = midi->module; + mod = hdl->module; inst = NULL; if (ch->bank < MIDI_BANKS) { - bank = module->tone[ch->bank * 2]; + bank = mod->tone[ch->bank * 2]; if (bank) { inst = bank[val]; } } if (inst == NULL) { - bank = midi->bank0[0]; + bank = hdl->bank0[0]; inst = bank[val]; } ch->inst = inst; bank = NULL; if (ch->bank < MIDI_BANKS) { - bank = module->tone[ch->bank * 2 + 1]; + bank = mod->tone[ch->bank * 2 + 1]; } if (bank == NULL) { - bank = midi->bank0[1]; + bank = hdl->bank0[1]; } ch->rhythm = bank; #else - ch->inst = midi->bank0[0][val]; + ch->inst = hdl->bank0[0][val]; #endif ch->program = val; } -static void chpressure(MIDIHDL midi, CHANNEL ch, int vel) { +static void VERMOUTHCL chpressure(MIDIHDL hdl, CHANNEL ch, int vel) { VOICE v; VOICE vterm; - v = midi->voice; - vterm = v + VOICE_MAX; + v = VOICEHDLPTR(hdl); + vterm = VOICEHDLEND(hdl); do { if ((v->phase & VOICE_ON) && (v->channel == ch)) { v->velocity = vel; @@ -601,7 +607,8 @@ static void chpressure(MIDIHDL midi, CHA } while(v < vterm); } -static void pitchbendor(MIDIHDL midi, CHANNEL ch, int val1, int val2) { +static void VERMOUTHCL pitchbendor(MIDIHDL hdl, CHANNEL ch, int val1, + int val2) { VOICE v; VOICE vterm; @@ -619,8 +626,8 @@ static void pitchbendor(MIDIHDL midi, CH ch->pitchfactor = bendhtbl[(val1 >> (6 + 7)) + 24] * bendltbl[(val1 >> 7) & 0x3f]; } - v = midi->voice; - vterm = v + VOICE_MAX; + v = VOICEHDLPTR(hdl); + vterm = VOICEHDLEND(hdl); do { if ((v->phase != VOICE_FREE) && (v->channel == ch)) { freq_update(v); @@ -630,7 +637,7 @@ static void pitchbendor(MIDIHDL midi, CH } } -static void allvolupdate(MIDIHDL midi) { +static void VERMOUTHCL allvolupdate(MIDIHDL hdl) { int level; CHANNEL ch; @@ -638,17 +645,17 @@ static void allvolupdate(MIDIHDL midi) { VOICE v; VOICE vterm; - level = gaintbl[midi->gain + 16] >> 1; - level *= midi->master; - midi->level = level; - ch = midi->channel; - chterm = ch + 16; + level = gaintbl[hdl->gain + 16] >> 1; + level *= hdl->master; + hdl->level = level; + ch = hdl->channel; + chterm = ch + CHANNEL_MAX; do { ch->level = (level * ch->volume * ch->expression) >> 14; ch++; } while(ch < chterm); - v = midi->voice; - vterm = v + VOICE_MAX; + v = VOICEHDLPTR(hdl); + vterm = VOICEHDLEND(hdl); do { if (v->phase & (VOICE_ON | VOICE_SUSTAIN)) { voice_volupdate(v); @@ -659,20 +666,20 @@ static void allvolupdate(MIDIHDL midi) { } #if defined(ENABLE_GSRX) -static void allresetmidi(MIDIHDL midi, BOOL gs) +static void VERMOUTHCL allresetmidi(MIDIHDL hdl, BOOL gs) #else #define allresetmidi(m, g) _allresetmidi(m) -static void _allresetmidi(MIDIHDL midi) +static void VERMOUTHCL _allresetmidi(MIDIHDL hdl) #endif { CHANNEL ch; CHANNEL chterm; UINT flag; - midi->master = 127; - ch = midi->channel; - chterm = ch + 16; - ZeroMemory(ch, sizeof(_CHANNEL) * 16); + hdl->master = 127; + ch = hdl->channel; + chterm = ch + CHANNEL_MAX; + ZeroMemory(ch, sizeof(_CHANNEL) * CHANNEL_MAX); flag = 0; do { ch->flag = flag++; @@ -681,7 +688,7 @@ static void _allresetmidi(MIDIHDL midi) ch->bank = 0; #endif ch->panpot = 64; - progchange(midi, ch, 0); + progchange(hdl, ch, 0); resetallcontrollers(ch); #if defined(ENABLE_GSRX) ch->keyshift = 0x40; @@ -700,8 +707,8 @@ static void _allresetmidi(MIDIHDL midi) #endif ch++; } while(ch < chterm); - allresetvoices(midi); - allvolupdate(midi); + allresetvoices(hdl); + allvolupdate(hdl); } @@ -714,12 +721,12 @@ VEXTERN UINT VEXPORT midiout_getver(char return((MIDIOUT_VERSION << 8) | 0x00); } -VEXTERN MIDIHDL VEXPORT midiout_create(MIDIMOD module, UINT worksize) { +VEXTERN MIDIHDL VEXPORT midiout_create(MIDIMOD mod, UINT worksize) { UINT size; MIDIHDL ret; - if (module == NULL) { + if (mod == NULL) { return(NULL); } worksize = min(worksize, 512); @@ -729,14 +736,14 @@ VEXTERN MIDIHDL VEXPORT midiout_create(M size += sizeof(_SAMPLE) * worksize; ret = (MIDIHDL)_MALLOC(size, "MIDIHDL"); if (ret) { - midimod_lock(module); + midimod_lock(mod); ZeroMemory(ret, size); - ret->samprate = module->samprate; + ret->samprate = mod->samprate; ret->worksize = worksize; - ret->module = module; + ret->module = mod; // ret->master = 127; - ret->bank0[0] = module->tone[0]; - ret->bank0[1] = module->tone[1]; + ret->bank0[0] = mod->tone[0]; + ret->bank0[1] = mod->tone[1]; ret->sampbuf = (SINT32 *)(ret + 1); ret->resampbuf = (SAMPLE)(ret->sampbuf + worksize * 2); allresetmidi(ret, FALSE); @@ -746,12 +753,12 @@ VEXTERN MIDIHDL VEXPORT midiout_create(M VEXTERN void VEXPORT midiout_destroy(MIDIHDL hdl) { - MIDIMOD module; + MIDIMOD mod; if (hdl) { - module = hdl->module; + mod = hdl->module; _MFREE(hdl); - midimod_lock(module); + midimod_lock(mod); } } @@ -808,7 +815,7 @@ VEXTERN void VEXPORT midiout_shortmsg(MI } } -static void longmsg_uni(MIDIHDL hdl, const UINT8 *msg, UINT size) { +static void VERMOUTHCL longmsg_uni(MIDIHDL hdl, const UINT8 *msg, UINT size) { if ((size >= 6) && (msg[2] == 0x7f)) { switch(msg[3]) { @@ -822,7 +829,7 @@ static void longmsg_uni(MIDIHDL hdl, con } } -static void longmsg_gm(MIDIHDL hdl, const UINT8 *msg, UINT size) { +static void VERMOUTHCL longmsg_gm(MIDIHDL hdl, const UINT8 *msg, UINT size) { if ((size >= 6) && (msg[2] == 0x7f)) { switch(msg[3]) { @@ -842,7 +849,7 @@ static void longmsg_gm(MIDIHDL hdl, cons } } -static void rolandcmd4(MIDIHDL hdl, UINT addr, UINT8 data) { +static void VERMOUTHCL rolandcmd4(MIDIHDL hdl, UINT addr, UINT8 data) { UINT part; CHANNEL ch; @@ -998,7 +1005,8 @@ static void rolandcmd4(MIDIHDL hdl, UINT } } -static void longmsg_roland(MIDIHDL hdl, const UINT8 *msg, UINT size) { +static void VERMOUTHCL longmsg_roland(MIDIHDL hdl, const UINT8 *msg, + UINT size) { UINT addr; UINT8 data; @@ -1058,33 +1066,27 @@ VEXTERN void VEXPORT midiout_longmsg(MID } } -VEXTERN const SINT32 * VEXPORT midiout_get(MIDIHDL hdl, UINT *samples) { +static UINT VERMOUTHCL preparepcm(MIDIHDL hdl, UINT size) { - UINT size; + UINT ret; + SINT32 *buf; VOICE v; VOICE vterm; - BOOL playing; - SINT32 *buf; SAMPLE src; SAMPLE srcterm; UINT cnt; UINT pos; UINT rem; - if ((hdl == NULL) || (samples == NULL)) { - goto moget_err; - } - size = min(*samples, hdl->worksize); - if (size == 0) { - goto moget_err; - } + ret = 0; + size = min(size, hdl->worksize); buf = hdl->sampbuf; ZeroMemory(buf, size * 2 * sizeof(SINT32)); - v = hdl->voice; - vterm = v + VOICE_MAX; - playing = FALSE; + v = VOICEHDLPTR(hdl); + vterm = VOICEHDLEND(hdl); do { if (v->phase != VOICE_FREE) { + ret = size; cnt = size; if (v->phase & VOICE_REL) { voice_setfree(v); @@ -1112,20 +1114,39 @@ VEXTERN const SINT32 * VEXPORT midiout_g if (src != srcterm) { v->mix(v, buf, src, srcterm); } - playing = TRUE; } v++; } while(v < vterm); + return(ret); +} - if (playing) { - *samples = size; - pos = 0; - do { - buf[pos*2+0] >>= (SAMP_SHIFT + 1); - buf[pos*2+1] >>= (SAMP_SHIFT + 1); - } while(++pos < size); - return(buf); +VEXTERN const SINT32 * VEXPORT midiout_get(MIDIHDL hdl, UINT *samples) { + + UINT size; + SINT32 *buf; + SINT32 *bufterm; + + if ((hdl == NULL) || (samples == NULL)) { + goto moget_err; + } + size = *samples; + if (size == 0) { + goto moget_err; } + size = preparepcm(hdl, size); + if (size == 0) { + goto moget_err; + } + + *samples = size; + buf = hdl->sampbuf; + bufterm = buf + (size * 2); + do { + buf[0] >>= (SAMP_SHIFT + 1); + buf[1] >>= (SAMP_SHIFT + 1); + buf += 2; + } while(buf < bufterm); + return(hdl->sampbuf); moget_err: return(NULL); @@ -1134,57 +1155,18 @@ moget_err: VEXTERN UINT VEXPORT midiout_get16(MIDIHDL hdl, SINT16 *pcm, UINT size) { UINT step; - VOICE v; - VOICE vterm; SINT32 *buf; - SAMPLE src; - SAMPLE srcterm; - UINT cnt; - UINT pos; - UINT rem; SINT32 l; SINT32 r; - if ((hdl != NULL) && (size)) { - do { - step = min(size, hdl->worksize); + if (hdl != NULL) { + while(size) { + step = preparepcm(hdl, size); + if (step == 0) { + break; + } size -= step; buf = hdl->sampbuf; - ZeroMemory(buf, step * 2 * sizeof(SINT32)); - v = hdl->voice; - vterm = v + VOICE_MAX; - do { - if (v->phase != VOICE_FREE) { - cnt = step; - if (v->phase & VOICE_REL) { - voice_setfree(v); - if (cnt > REL_COUNT) { - cnt = REL_COUNT; - } - } - if (v->flag & VOICE_FIXPITCH) { - pos = v->samppos >> FREQ_SHIFT; - src = v->sample->data + pos; - rem = (v->sample->datasize >> FREQ_SHIFT) - pos; - if (cnt < rem) { - v->samppos += cnt << FREQ_SHIFT; - srcterm = src + cnt; - } - else { - voice_setfree(v); - srcterm = src + rem; - } - } - else { - src = hdl->resampbuf; - srcterm = v->resamp(v, src, src + cnt); - } - if (src != srcterm) { - v->mix(v, buf, src, srcterm); - } - } - v++; - } while(v < vterm); do { l = pcm[0]; r = pcm[1]; @@ -1207,69 +1189,31 @@ VEXTERN UINT VEXPORT midiout_get16(MIDIH buf += 2; pcm += 2; } while(--step); - } while(size); + } } - return(0);} + return(0); +} VEXTERN UINT VEXPORT midiout_get32(MIDIHDL hdl, SINT32 *pcm, UINT size) { UINT step; - VOICE v; - VOICE vterm; SINT32 *buf; - SAMPLE src; - SAMPLE srcterm; - UINT cnt; - UINT pos; - UINT rem; - if ((hdl != NULL) && (size)) { - do { - step = min(size, hdl->worksize); + if (hdl != NULL) { + while(size) { + step = preparepcm(hdl, size); + if (step == 0) { + break; + } size -= step; buf = hdl->sampbuf; - ZeroMemory(buf, step * 2 * sizeof(SINT32)); - v = hdl->voice; - vterm = v + VOICE_MAX; - do { - if (v->phase != VOICE_FREE) { - cnt = step; - if (v->phase & VOICE_REL) { - voice_setfree(v); - if (cnt > REL_COUNT) { - cnt = REL_COUNT; - } - } - if (v->flag & VOICE_FIXPITCH) { - pos = v->samppos >> FREQ_SHIFT; - src = v->sample->data + pos; - rem = (v->sample->datasize >> FREQ_SHIFT) - pos; - if (cnt < rem) { - v->samppos += cnt << FREQ_SHIFT; - srcterm = src + cnt; - } - else { - voice_setfree(v); - srcterm = src + rem; - } - } - else { - src = hdl->resampbuf; - srcterm = v->resamp(v, src, src + cnt); - } - if (src != srcterm) { - v->mix(v, buf, src, srcterm); - } - } - v++; - } while(v < vterm); do { pcm[0] += buf[0] >> (SAMP_SHIFT + 1); pcm[1] += buf[1] >> (SAMP_SHIFT + 1); buf += 2; pcm += 2; } while(--step); - } while(size); + } } return(0); }