Exemplo n.º 1
0
int mmd_load_hybrid_instrument(HIO_HANDLE *f, struct module_data *m, int i,
			int smp_idx, struct SynthInstr *synth,
			struct InstrExt *exp_smp, struct MMD0sample *sample)
{
	struct xmp_module *mod = &m->mod;
	struct xmp_instrument *xxi = &mod->xxi[i];
	struct xmp_subinstrument *sub;
	struct xmp_sample *xxs;
	int length, type;
	int pos = hio_tell(f);

	synth->defaultdecay = hio_read8(f);
	hio_seek(f, 3, SEEK_CUR);
	synth->rep = hio_read16b(f);
	synth->replen = hio_read16b(f);
	synth->voltbllen = hio_read16b(f);
	synth->wftbllen = hio_read16b(f);
	synth->volspeed = hio_read8(f);
	synth->wfspeed = hio_read8(f);
	synth->wforms = hio_read16b(f);
	hio_read(synth->voltbl, 1, 128, f);;
	hio_read(synth->wftbl, 1, 128, f);;

	hio_seek(f, pos - 6 + hio_read32b(f), SEEK_SET);
	length = hio_read32b(f);
	type = hio_read16b(f);

	if (med_new_instrument_extras(xxi) != 0)
		return -1;

	xxi->nsm = 1;
	if (subinstrument_alloc(mod, i, 1) < 0)
		return -1;

	MED_INSTRUMENT_EXTRAS((*xxi))->vts = synth->volspeed;
	MED_INSTRUMENT_EXTRAS((*xxi))->wts = synth->wfspeed;

	sub = &xxi->sub[0];

	sub->pan = 0x80;
	sub->vol = sample->svol;
	sub->xpo = sample->strans;
	sub->sid = smp_idx;
	sub->fin = exp_smp->finetune;

	xxs = &mod->xxs[smp_idx];

	xxs->len = length;
	xxs->lps = 2 * sample->rep;
	xxs->lpe = xxs->lps + 2 * sample->replen;
	xxs->flg = sample->replen > 1 ?  XMP_SAMPLE_LOOP : 0;

	if (load_sample(m, f, 0, xxs, NULL) < 0)
		return -1;

	return 0;
}
Exemplo n.º 2
0
int med_new_instrument_extras(struct xmp_instrument *xxi)
{
	xxi->extra = calloc(1, sizeof(struct med_instrument_extras));
	if (xxi->extra == NULL)
		return -1;
	MED_INSTRUMENT_EXTRAS((*xxi))->magic = MED_EXTRAS_MAGIC;

	return 0;
}
Exemplo n.º 3
0
int mmd_load_synth_instrument(HIO_HANDLE *f, struct module_data *m, int i,
			int smp_idx, struct SynthInstr *synth,
			struct InstrExt *exp_smp, struct MMD0sample *sample)
{
	struct xmp_module *mod = &m->mod;
	struct xmp_instrument *xxi = &mod->xxi[i];
	int pos = hio_tell(f);
	int j;

	synth->defaultdecay = hio_read8(f);
	hio_seek(f, 3, SEEK_CUR);
	synth->rep = hio_read16b(f);
	synth->replen = hio_read16b(f);
	synth->voltbllen = hio_read16b(f);
	synth->wftbllen = hio_read16b(f);
	synth->volspeed = hio_read8(f);
	synth->wfspeed = hio_read8(f);
	synth->wforms = hio_read16b(f);
	hio_read(synth->voltbl, 1, 128, f);;
	hio_read(synth->wftbl, 1, 128, f);;
	for (j = 0; j < 64; j++)
		synth->wf[j] = hio_read32b(f);

	D_(D_INFO "  VS:%02x WS:%02x WF:%02x %02x %+3d %+1d",
			synth->volspeed, synth->wfspeed,
			synth->wforms & 0xff,
			sample->svol,
			sample->strans,
			exp_smp->finetune);

	if (synth->wforms == 0xffff)	
		return 1;
	if (synth->wforms > 64)
	  return -1;

	if (med_new_instrument_extras(&mod->xxi[i]) != 0)
		return -1;

	mod->xxi[i].nsm = synth->wforms;
	if (subinstrument_alloc(mod, i, synth->wforms) < 0)
		return -1;

	MED_INSTRUMENT_EXTRAS((*xxi))->vts = synth->volspeed;
	MED_INSTRUMENT_EXTRAS((*xxi))->wts = synth->wfspeed;

	for (j = 0; j < synth->wforms; j++) {
		struct xmp_subinstrument *sub = &xxi->sub[j];
		struct xmp_sample *xxs = &mod->xxs[smp_idx];

		sub->pan = 0x80;
		sub->vol = sample->svol;
		sub->xpo = sample->strans - 24;
		sub->sid = smp_idx;
		sub->fin = exp_smp->finetune;

		hio_seek(f, pos - 6 + synth->wf[j], SEEK_SET);

		xxs->len = hio_read16b(f) * 2;
		xxs->lps = 0;
		xxs->lpe = mod->xxs[smp_idx].len;
		xxs->flg = XMP_SAMPLE_LOOP;

		if (load_sample(m, f, 0, xxs, NULL) < 0)
			return -1;

		smp_idx++;
	}

	return 0;
}
Exemplo n.º 4
0
void med_play_extras(struct context_data *ctx, struct channel_data *xc, int chn)
{
	struct module_data *m = &ctx->m;
	struct player_data *p = &ctx->p;
	struct xmp_module *mod = &m->mod;
	struct med_module_extras *me;
	struct med_channel_extras *ce;
	struct med_instrument_extras *ie;
	int b, jws = 0, jvs = 0, loop;
	int temp;

	if (!HAS_MED_MODULE_EXTRAS(*m))
		return;

	me = (struct med_module_extras *)m->extra;
	ce = (struct med_channel_extras *)xc->extra;
	ie = MED_INSTRUMENT_EXTRAS(m->mod.xxi[xc->ins]);

	/* Handle hold/decay */

	/* on the first row of a held note, continue note if ce->hold is 2
	 * (this is set after pre-fetching the next row and see if we
	 * continue to hold. On remaining rows with hold on, we have the
	 * FX_MED_HOLD effect and ce->hold set to 1. On the last row, see
	 * if ce->hold_count is set (meaning that a note was held) and
	 * ce->hold is 0 (meaning that it's not held anymore). Then
	 * procceed with normal frame counting until decay.
	 */

	if (ce->hold_count) {		/* was held in the past */
		if (!ce->hold && p->frame >= ie->hold) { /* but not now */
			SET_NOTE(NOTE_FADEOUT);
			ce->hold_count = 0;
		}
	} else if (ie->hold) {		/* has instrument hold */
		if (p->frame >= ie->hold && ce->hold == 0) {
			SET_NOTE(NOTE_FADEOUT);
		}
	}

	if (p->frame == (p->speed - 1) && ce->hold != 2) {
		ce->hold = 0;
	}

	/* Handle synth */

	if (me->vol_table[xc->ins] == NULL || me->wav_table[xc->ins] == NULL) {
		ce->volume = 64;  /* we need this in extras_get_volume() */
		return;
	}

	if (p->frame == 0 && TEST(NEW_NOTE)) {
		ce->period = xc->period;
		if (TEST(NEW_INS)) {
			ce->arp = ce->aidx = 0;
			ce->vp = ce->vc = ce->vw = 0;
			ce->wp = ce->wc = ce->ww = 0;
			ce->env_wav = -1;
			ce->env_idx = 0;
			ce->flags &= ~MED_SYNTH_ENV_LOOP;
			ce->vv = 0;
			ce->wv = 0;
			ce->vs = ie->vts;
			ce->ws = ie->wts;
		}
	}

	if (ce->vs > 0 && ce->vc-- == 0) {
		ce->vc = ce->vs - 1;

		if (ce->vw > 0) {
			ce->vw--;
			goto skip_vol;
		}

		loop = jws = 0;

		/* Volume commands */

	    next_vt:
		switch (b = VT) {
		case 0xff:	/* END */
		case 0xfb:	/* HLT */
			ce->vp--;
			break;
		case 0xfe:	/* JMP */
			if (loop)	/* avoid infinite loop */
				break;
			temp = VT;
			ce->vp = temp;
			loop = 1;
			goto next_vt;
			break;
		case 0xfa:	/* JWS */
			jws = VT;
			break;
		case 0xf5:	/* EN2 */
			ce->env_wav = VT;
			ce->flags |= MED_SYNTH_ENV_LOOP;
			break;
		case 0xf4:	/* EN1 */
			ce->env_wav = VT;
			break;
		case 0xf3:	/* CHU */
			ce->vv = VT;
			break;
		case 0xf2:	/* CHD */
			ce->vv = -VT;
			break;
		case 0xf1:	/* WAI */
			ce->vw = VT;
			break;
		case 0xf0:	/* SPD */
			ce->vs = VT;
			break;
		default:
			if (b >= 0x00 && b <= 0x40)
				ce->volume = b;
		}

	    skip_vol:

		/* volume envelope */
		if (ce->env_wav >= 0) {
			int sid = mod->xxi[xc->ins].sub[ce->env_wav].sid;
			struct xmp_sample *xxs = &mod->xxs[sid];
			if (xxs->len == 0x80) {		/* sanity check */
				ce->volume = ((int8)xxs->data[ce->env_idx] + 0x80) >> 2;
				ce->env_idx++;

				if (ce->env_idx >= 0x80) {
					if (~ce->flags & MED_SYNTH_ENV_LOOP) {
						ce->env_wav = -1;
					}
					ce->env_idx = 0;
				}
			}
Exemplo n.º 5
0
void med_play_extras(struct context_data *ctx, struct channel_data *xc, int chn,
		     int new_note)
{
	struct module_data *m = &ctx->m;
	struct med_module_extras *me;
	struct med_channel_extras *ce;
	int b, jws = 0, jvs = 0, loop;
	int temp;

	if (!HAS_MED_MODULE_EXTRAS(*m))
		return;

	me = (struct med_module_extras *)m->extra;
	ce = (struct med_channel_extras *)xc->extra;

	if (me->vol_table[xc->ins] == NULL || me->wav_table[xc->ins] == NULL)
		return;

	if (new_note) {
		ce->arp = ce->aidx = 0;
		ce->period = xc->period;
		ce->vp = ce->vc = ce->vw = 0;
		ce->wp = ce->wc = ce->ww = 0;
		ce->vv = 0;
		ce->vs = MED_INSTRUMENT_EXTRAS(m->mod.xxi[xc->ins])->vts;
		ce->ws = MED_INSTRUMENT_EXTRAS(m->mod.xxi[xc->ins])->wts;
	}

	if (ce->vs > 0 && ce->vc-- == 0) {
		ce->vc = ce->vs - 1;

		if (ce->vw > 0) {
			ce->vw--;
			goto skip_vol;
		}

		loop = jws = 0;

	    next_vt:
		switch (b = VT) {
		case 0xff:	/* END */
		case 0xfb:	/* HLT */
			ce->vp--;
			break;
		case 0xfe:	/* JMP */
			if (loop)	/* avoid infinite loop */
				break;
			temp = VT;
			ce->vp = temp;
			loop = 1;
			goto next_vt;
			break;
		case 0xfa:	/* JWS */
			jws = VT;
			break;
		case 0xf5:	/* EN2 */
		case 0xf4:	/* EN1 */
			VT_SKIP;	/* Not implemented */
			break;
		case 0xf3:	/* CHU */
			ce->vv = VT;
			break;
		case 0xf2:	/* CHD */
			ce->vv = -VT;
			break;
		case 0xf1:	/* WAI */
			ce->vw = VT;
			break;
		case 0xf0:	/* SPD */
			ce->vs = VT;
			break;
		default:
			if (b >= 0x00 && b <= 0x40)
				ce->volume = b;
		}

		ce->volume += ce->vv;
		CLAMP(ce->volume, 0, 64);

	    skip_vol:

		if (ce->ww > 0) {
			ce->ww--;
			goto skip_wav;
		}

		loop = jvs = 0;

	    next_wt:
		switch (b = WT) {
			struct xmp_instrument *xxi;

		case 0xff:	/* END */
		case 0xfb:	/* HLT */
			ce->wp--;
			break;
		case 0xfe:	/* JMP */
			if (loop)	/* avoid infinite loop */
				break;
			temp = WT;
			if (temp == 0xff) {	/* handle JMP END case */
				ce->wp--;	/* see lepeltheme ins 0x02 */
				break;
			}
			ce->wp = temp;
			loop = 1;
			goto next_wt;
		case 0xfd:	/* ARE */
			break;
		case 0xfc:	/* ARP */
			ce->arp = ce->aidx = ce->wp++;
			while (WT != 0xfd) ;
			break;
		case 0xfa:	/* JVS */
			jws = WT;
			break;
		case 0xf7:	/* VWF */
			ce->vwf = WT;
			break;
		case 0xf6:	/* RES */
			xc->period = ce->period;
			break;
		case 0xf5:	/* VBS */
			ce->vib_speed = WT;
			break;
		case 0xf4:	/* VBD */
			ce->vib_depth = WT;
			break;
		case 0xf3:	/* CHU */
			ce->wv = -WT;
			break;
		case 0xf2:	/* CHD */
			ce->wv = WT;
			break;
		case 0xf1:	/* WAI */
			ce->ww = WT;
			break;
		case 0xf0:	/* SPD */
			ce->ws = WT;
			break;
		default:
			xxi = &m->mod.xxi[xc->ins];
			if (b < xxi->nsm && xxi->sub[b].sid != xc->smp) {
				xc->smp = xxi->sub[b].sid;
				virt_setsmp(ctx, chn, xc->smp);
			}
		}
	    skip_wav:
		;
		/* xc->period += ce->wv; */
	}

	if (jws) {
		ce->wp = jws;
		jws = 0;
	}

	if (jvs) {
		ce->vp = jvs;
		jvs = 0;
	}
}