コード例 #1
0
ファイル: extras.c プロジェクト: GCrean/libxmp
void release_module_extras(struct context_data *ctx)
{
	struct module_data *m = &ctx->m;

	if (HAS_MED_MODULE_EXTRAS(*m))
		med_release_module_extras(m);
	else if (HAS_HMN_MODULE_EXTRAS(*m))
		hmn_release_module_extras(m);
}
コード例 #2
0
ファイル: extras.c プロジェクト: GCrean/libxmp
int new_channel_extras(struct context_data *ctx, struct channel_data *xc)
{
	struct module_data *m = &ctx->m;

	if (HAS_MED_MODULE_EXTRAS(*m)) {
		if (med_new_channel_extras(xc) < 0)
			return -1;
	} else if (HAS_HMN_MODULE_EXTRAS(*m)) {
		if (hmn_new_channel_extras(xc) < 0)
			return -1;
	}

	return 0;
}
コード例 #3
0
ファイル: med_extras.c プロジェクト: Nlcke/gideros
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;
				}
			}
コード例 #4
0
ファイル: med_extras.c プロジェクト: GCrean/libxmp
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;
	}
}