示例#1
0
文件: no_load.c 项目: eltoder/libxmp
static int no_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	struct xmp_event *event;
	int i, j, k;
	int nsize;

	LOAD_INIT();

	hio_read32b(f);			/* NO 0x00 0x00 */

	set_type(m, "Liquid Tracker");

	nsize = hio_read8(f);
	for (i = 0; i < nsize; i++) {
		uint8 x = hio_read8(f);
		if (i < XMP_NAME_SIZE)
			mod->name[i] = x;
	}

	hio_read16l(f);
	hio_read16l(f);
	hio_read16l(f);
	hio_read16l(f);
	hio_read8(f);
	mod->pat = hio_read8(f);
	hio_read8(f);
	mod->chn = hio_read8(f);
	mod->trk = mod->pat * mod->chn;
	hio_read8(f);
	hio_read16l(f);
	hio_read16l(f);
	hio_read8(f);
	mod->ins = mod->smp = 63;

	for (i = 0; i < 256; i++) {
		uint8 x = hio_read8(f);
		if (x == 0xff)
			break;
		mod->xxo[i] = x;
	}
	hio_seek(f, 255 - i, SEEK_CUR);
	mod->len = i;

	MODULE_INFO();

	if (instrument_init(mod) < 0)
		return -1;

	/* Read instrument names */
	for (i = 0; i < mod->ins; i++) {
		int hasname, c2spd;

		if (subinstrument_alloc(mod, i, 1) < 0)
			return -1;

		nsize = hio_read8(f);
		hasname = 0;
		for (j = 0; j < nsize; j++) {
			uint8 x = hio_read8(f);
			if (x != 0x20)
				hasname = 1;
			if (j < 32)
				mod->xxi[i].name[j] = x;
		}
		if (!hasname)
			mod->xxi[i].name[0] = 0;

		hio_read32l(f);
		hio_read32l(f);
		mod->xxi[i].sub[0].vol = hio_read8(f);
		c2spd = hio_read16l(f);
		mod->xxs[i].len = hio_read16l(f);
		mod->xxs[i].lps = hio_read16l(f);
		mod->xxs[i].lpe = hio_read16l(f);
		hio_read32l(f);
		hio_read16l(f);

		if (mod->xxs[i].len > 0)
			mod->xxi[i].nsm = 1;

		/*
		mod->xxs[i].lps = 0;
		mod->xxs[i].lpe = 0;
		*/
		mod->xxs[i].flg = mod->xxs[i].lpe > 0 ? XMP_SAMPLE_LOOP : 0;
		mod->xxi[i].sub[0].fin = 0;
		mod->xxi[i].sub[0].pan = 0x80;
		mod->xxi[i].sub[0].sid = i;

		D_(D_INFO "[%2X] %-22.22s  %04x %04x %04x %c V%02x %5d",
				i, mod->xxi[i].name,
				mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
				mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
				mod->xxi[i].sub[0].vol, c2spd);

		c2spd = 8363 * c2spd / 8448;
		c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
	}

	if (pattern_init(mod) < 0)
		return -1;

	/* Read and convert patterns */
	D_(D_INFO "Stored patterns: %d ", mod->pat);

	for (i = 0; i < mod->pat; i++) {
		if (pattern_tracks_alloc(mod, i, 64) < 0)
			return -1;

		for (j = 0; j < mod->xxp[i]->rows; j++) {
			for (k = 0; k < mod->chn; k++) {
				uint32 x, note, ins, vol, fxt, fxp;

				event = &EVENT (i, k, j);

				x = hio_read32l(f);
				note = x & 0x0000003f;
				ins = (x & 0x00001fc0) >> 6;
				vol = (x & 0x000fe000) >> 13;
				fxt = (x & 0x00f00000) >> 20;
				fxp = (x & 0xff000000) >> 24;

				if (note != 0x3f)
					event->note = 36 + note;
				if (ins != 0x7f)
					event->ins = 1 + ins;
				if (vol != 0x7f)
					event->vol = vol;
				if (fxt != 0x0f) {
					event->fxt = fx[fxt];
					event->fxp = fxp;
				}
			}
		}
	}

	/* Read samples */
	D_(D_INFO "Stored samples: %d", mod->smp);

	for (i = 0; i < mod->ins; i++) {
		if (mod->xxs[i].len == 0)
			continue;
		if (load_sample(m, f, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
			return -1;
	}

	m->quirk |= QUIRKS_ST3;
	m->read_event_type = READ_EVENT_ST3;

	return 0;
}
示例#2
0
static int get_patt(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
{
	struct xmp_module *mod = &m->mod;
	struct xmp_event *event, dummy;
	int i, len, chan;
	int rows, r;
	uint8 flag;
	
	i = hio_read8(f);	/* pattern number */
	len = hio_read32l(f);
	
	/* Sanity check */
	if (i >= mod->pat || len <= 0) {
		return -1;
	}

	rows = hio_read8(f) + 1;

	if (pattern_tracks_alloc(mod, i, rows) < 0)
		return -1;

	for (r = 0; r < rows; ) {
		if ((flag = hio_read8(f)) == 0) {
			r++;
			continue;
		}

		chan = flag & 0x1f;

		event = chan < mod->chn ? &EVENT(i, chan, r) : &dummy;

		if (flag & 0x80) {
			uint8 fxp = hio_read8(f);
			uint8 fxt = hio_read8(f);

			switch (fxt) {
			case 0x14:		/* speed */
				fxt = FX_S3M_SPEED;
				break;
			default:
				if (fxt > 0x0f) {
					printf("unknown effect %02x %02x\n", fxt, fxp);
					fxt = fxp = 0;
				}
			}

			event->fxt = fxt;
			event->fxp = fxp;
		}

		if (flag & 0x40) {
			event->ins = hio_read8(f);
			event->note = hio_read8(f);

			if (event->note == 128) {
				event->note = XMP_KEY_OFF;
			}
		}

		if (flag & 0x20) {
			event->vol = 1 + hio_read8(f) / 2;
		}
	}

	return 9;
}
示例#3
0
static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
{
	struct xmp_module *mod = &m->mod;
	struct local_data *data = (struct local_data *)parm;
	int i, j;
	int srate, finetune, flags;
	int val, vwf, vra, vde, vsw, fade;
	uint8 buf[30];

	hio_read8(f);		/* 00 */
	i = hio_read8(f);		/* instrument number */

	hio_read(&mod->xxi[i].name, 1, 28, f);
	adjust_string((char *)mod->xxi[i].name);

	mod->xxi[i].nsm = hio_read8(f);

	for (j = 0; j < 108; j++) {
		mod->xxi[i].map[j].ins = hio_read8(f);
	}

	hio_seek(f, 11, SEEK_CUR);		/* unknown */
	vwf = hio_read8(f);			/* vibrato waveform */
	vsw = hio_read8(f);			/* vibrato sweep */
	hio_read8(f);			/* unknown */
	hio_read8(f);			/* unknown */
	vde = hio_read8(f);		/* vibrato depth */
	vra = hio_read16l(f) / 16;		/* vibrato speed */
	hio_read8(f);			/* unknown */

	val = hio_read8(f);			/* PV envelopes flags */
	if (LSN(val) & 0x01)
		mod->xxi[i].aei.flg |= XMP_ENVELOPE_ON;
	if (LSN(val) & 0x02)
		mod->xxi[i].aei.flg |= XMP_ENVELOPE_SUS;
	if (LSN(val) & 0x04)
		mod->xxi[i].aei.flg |= XMP_ENVELOPE_LOOP;
	if (MSN(val) & 0x01)
		mod->xxi[i].pei.flg |= XMP_ENVELOPE_ON;
	if (MSN(val) & 0x02)
		mod->xxi[i].pei.flg |= XMP_ENVELOPE_SUS;
	if (MSN(val) & 0x04)
		mod->xxi[i].pei.flg |= XMP_ENVELOPE_LOOP;

	val = hio_read8(f);			/* PV envelopes points */
	mod->xxi[i].aei.npt = LSN(val) + 1;
	mod->xxi[i].pei.npt = MSN(val) + 1;

	val = hio_read8(f);			/* PV envelopes sustain point */
	mod->xxi[i].aei.sus = LSN(val);
	mod->xxi[i].pei.sus = MSN(val);

	val = hio_read8(f);			/* PV envelopes loop start */
	mod->xxi[i].aei.lps = LSN(val);
	mod->xxi[i].pei.lps = MSN(val);

	hio_read8(f);			/* PV envelopes loop end */
	mod->xxi[i].aei.lpe = LSN(val);
	mod->xxi[i].pei.lpe = MSN(val);

	if (mod->xxi[i].aei.npt <= 0 || mod->xxi[i].aei.npt >= XMP_MAX_ENV_POINTS)
		mod->xxi[i].aei.flg &= ~XMP_ENVELOPE_ON;

	if (mod->xxi[i].pei.npt <= 0 || mod->xxi[i].pei.npt >= XMP_MAX_ENV_POINTS)
		mod->xxi[i].pei.flg &= ~XMP_ENVELOPE_ON;

	hio_read(buf, 1, 30, f);		/* volume envelope points */;
	for (j = 0; j < mod->xxi[i].aei.npt; j++) {
		mod->xxi[i].aei.data[j * 2] = readmem16l(buf + j * 3) / 16;
		mod->xxi[i].aei.data[j * 2 + 1] = buf[j * 3 + 2];
	}

	hio_read(buf, 1, 30, f);		/* pan envelope points */;
	for (j = 0; j < mod->xxi[i].pei.npt; j++) {
		mod->xxi[i].pei.data[j * 2] = readmem16l(buf + j * 3) / 16;
		mod->xxi[i].pei.data[j * 2 + 1] = buf[j * 3 + 2];
	}

	fade = hio_read8(f);		/* fadeout - 0x80->0x02 0x310->0x0c */
	hio_read8(f);			/* unknown */

	D_(D_INFO "[%2X] %-28.28s  %2d ", i, mod->xxi[i].name, mod->xxi[i].nsm);

	if (mod->xxi[i].nsm == 0)
		return 0;

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

	for (j = 0; j < mod->xxi[i].nsm; j++, data->snum++) {
		hio_read32b(f);	/* SAMP */
		hio_read32b(f);	/* size */
	
		hio_read(&mod->xxs[data->snum].name, 1, 28, f);
		adjust_string((char *)mod->xxs[data->snum].name);
	
		mod->xxi[i].sub[j].pan = hio_read8(f) * 4;
		if (mod->xxi[i].sub[j].pan == 0)	/* not sure about this */
			mod->xxi[i].sub[j].pan = 0x80;
		
		mod->xxi[i].sub[j].vol = hio_read8(f);
		flags = hio_read8(f);
		hio_read8(f);	/* unknown - 0x80 */

		mod->xxi[i].sub[j].vwf = vwf;
		mod->xxi[i].sub[j].vde = vde;
		mod->xxi[i].sub[j].vra = vra;
		mod->xxi[i].sub[j].vsw = vsw;
		mod->xxi[i].sub[j].sid = data->snum;
	
		mod->xxs[data->snum].len = hio_read32l(f);
		mod->xxs[data->snum].lps = hio_read32l(f);
		mod->xxs[data->snum].lpe = hio_read32l(f);
	
		mod->xxs[data->snum].flg = 0;
		if (flags & 0x04)
			mod->xxs[data->snum].flg |= XMP_SAMPLE_16BIT;
		if (flags & 0x08)
			mod->xxs[data->snum].flg |= XMP_SAMPLE_LOOP;
		if (flags & 0x10)
			mod->xxs[data->snum].flg |= XMP_SAMPLE_LOOP_BIDIR;
		/* if (flags & 0x80)
			mod->xxs[data->snum].flg |= ? */
	
		srate = hio_read32l(f);
		finetune = 0;
		c2spd_to_note(srate, &mod->xxi[i].sub[j].xpo, &mod->xxi[i].sub[j].fin);
		mod->xxi[i].sub[j].fin += finetune;
	
		hio_read32l(f);			/* 0x00000000 */
		hio_read32l(f);			/* unknown */
	
		D_(D_INFO "  %X: %05x%c%05x %05x %c V%02x P%02x %5d",
			j, mod->xxs[data->snum].len,
			mod->xxs[data->snum].flg & XMP_SAMPLE_16BIT ? '+' : ' ',
			mod->xxs[data->snum].lps,
			mod->xxs[data->snum].lpe,
			mod->xxs[data->snum].flg & XMP_SAMPLE_LOOP_BIDIR ? 'B' : 
			mod->xxs[data->snum].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
			mod->xxi[i].sub[j].vol,
			mod->xxi[i].sub[j].pan,
			srate);
	
		if (mod->xxs[data->snum].len > 1) {
			int snum = data->snum;
			if (load_sample(m, f, 0, &mod->xxs[snum], NULL) < 0)
				return -1;
		}
	}

	return 0;
}
示例#4
0
static int get_inst(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
{
	struct xmp_module *mod = &m->mod;
	int i, srate, finetune, flags;
	int has_unsigned_sample;

	hio_read32b(f);		/* 42 01 00 00 */
	hio_read8(f);		/* 00 */
	i = hio_read8(f);		/* instrument number */
	
	hio_read(&mod->xxi[i].name, 1, 28, f);
	hio_seek(f, 290, SEEK_CUR);	/* Sample/note map, envelopes */
	mod->xxi[i].nsm = hio_read16l(f);

	D_(D_INFO "[%2X] %-28.28s  %2d ", i, mod->xxi[i].name, mod->xxi[i].nsm);

	if (mod->xxi[i].nsm == 0)
		return 0;

	if (libxmp_alloc_subinstrument(mod, i, mod->xxi[i].nsm) < 0)
		return -1;

	/* FIXME: Currently reading only the first sample */

	hio_read32b(f);	/* RIFF */
	hio_read32b(f);	/* size */
	hio_read32b(f);	/* AS   */
	hio_read32b(f);	/* SAMP */
	hio_read32b(f);	/* size */
	hio_read32b(f);	/* unknown - usually 0x40000000 */

	hio_read(&mod->xxs[i].name, 1, 28, f);

	hio_read32b(f);	/* unknown - 0x0000 */
	hio_read8(f);	/* unknown - 0x00 */

	mod->xxi[i].sub[0].sid = i;
	mod->xxi[i].vol = hio_read8(f);
	mod->xxi[i].sub[0].pan = 0x80;
	mod->xxi[i].sub[0].vol = (hio_read16l(f) + 1) / 512;
	flags = hio_read16l(f);
	hio_read16l(f);			/* unknown - 0x0080 */
	mod->xxs[i].len = hio_read32l(f);
	mod->xxs[i].lps = hio_read32l(f);
	mod->xxs[i].lpe = hio_read32l(f);

	mod->xxs[i].flg = 0;
	has_unsigned_sample = 0;
	if (flags & 0x04)
		mod->xxs[i].flg |= XMP_SAMPLE_16BIT;
	if (flags & 0x08)
		mod->xxs[i].flg |= XMP_SAMPLE_LOOP;
	if (flags & 0x10)
		mod->xxs[i].flg |= XMP_SAMPLE_LOOP | XMP_SAMPLE_LOOP_BIDIR;
	if (~flags & 0x80)
		has_unsigned_sample = 1;

	srate = hio_read32l(f);
	finetune = 0;
	libxmp_c2spd_to_note(srate, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
	mod->xxi[i].sub[0].fin += finetune;

	hio_read32l(f);			/* 0x00000000 */
	hio_read32l(f);			/* unknown */

	D_(D_INFO "  %x: %05x%c%05x %05x %c V%02x %04x %5d",
		0, mod->xxs[i].len,
		mod->xxs[i].flg & XMP_SAMPLE_16BIT ? '+' : ' ',
		mod->xxs[i].lps,
		mod->xxs[i].lpe,
		mod->xxs[i].flg & XMP_SAMPLE_LOOP_BIDIR ? 'B' : 
			mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
		mod->xxi[i].sub[0].vol, flags, srate);

	if (mod->xxs[i].len > 1) {
		if (libxmp_load_sample(m, f, has_unsigned_sample ?
				SAMPLE_FLAG_UNS : 0, &mod->xxs[i], NULL) < 0)
			return -1;
	}

	return 0;
}
示例#5
0
文件: s3m_load.c 项目: Nlcke/gideros
static int s3m_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
    struct xmp_module *mod = &m->mod;
    int c, r, i;
    struct xmp_event *event = 0, dummy;
    struct s3m_file_header sfh;
    struct s3m_instrument_header sih;
#ifndef LIBXMP_CORE_PLAYER
    struct s3m_adlib_header sah;
    char tracker_name[40];
    int quirk87 = 0;
#endif
    int pat_len;
    uint8 n, b, x8;
    uint16 *pp_ins;		/* Parapointers to instruments */
    uint16 *pp_pat;		/* Parapointers to patterns */
    int ret;

    LOAD_INIT();

    hio_read(&sfh.name, 28, 1, f);	/* Song name */
    hio_read8(f);			/* 0x1a */
    sfh.type = hio_read8(f);		/* File type */
    hio_read16l(f);			/* Reserved */
    sfh.ordnum = hio_read16l(f);	/* Number of orders (must be even) */
    sfh.insnum = hio_read16l(f);	/* Number of instruments */
    sfh.patnum = hio_read16l(f);	/* Number of patterns */
    sfh.flags = hio_read16l(f);		/* Flags */
    sfh.version = hio_read16l(f);	/* Tracker ID and version */
    sfh.ffi = hio_read16l(f);		/* File format information */

    /* Sanity check */
    if (sfh.ffi != 1 && sfh.ffi != 2) {
	goto err;
    }
    if (sfh.ordnum > 255 || sfh.insnum > 255 || sfh.patnum > 255) {
	goto err;
    }

    sfh.magic = hio_read32b(f);		/* 'SCRM' */
    sfh.gv = hio_read8(f);		/* Global volume */
    sfh.is = hio_read8(f);		/* Initial speed */
    sfh.it = hio_read8(f);		/* Initial tempo */
    sfh.mv = hio_read8(f);		/* Master volume */
    sfh.uc = hio_read8(f);		/* Ultra click removal */
    sfh.dp = hio_read8(f);		/* Default pan positions if 0xfc */
    hio_read32l(f);			/* Reserved */
    hio_read32l(f);			/* Reserved */
    sfh.special = hio_read16l(f);	/* Ptr to special custom data */
    hio_read(sfh.chset, 32, 1, f);	/* Channel settings */

#if 0
    if (sfh.magic != MAGIC_SCRM)
	return -1;
#endif

#ifndef LIBXMP_CORE_PLAYER
    /* S3M anomaly in return_of_litmus.s3m */
    if (sfh.version == 0x1301 && sfh.name[27] == 0x87)
	quirk87 = 1;

    if (quirk87) {
	fix87(sfh.name);
	fix87(sfh.patnum);
	fix87(sfh.flags);
    }
#endif

    copy_adjust(mod->name, sfh.name, 28);

    pp_ins = calloc(2, sfh.insnum);
    if (pp_ins == NULL)
	goto err;

    pp_pat = calloc (2, sfh.patnum);
    if (pp_pat == NULL)
	goto err2;

    if (sfh.flags & S3M_AMIGA_RANGE)
	m->quirk |= QUIRK_MODRNG;
    if (sfh.flags & S3M_ST300_VOLS)
	m->quirk |= QUIRK_VSALL;
    /* m->volbase = 4096 / sfh.gv; */
    mod->spd = sfh.is;
    mod->bpm = sfh.it;
    mod->chn = 0;
    
    for (i = 0; i < 32; i++) {
	if (sfh.chset[i] == S3M_CH_OFF)
	    continue;

	mod->chn = i + 1;

	if (sfh.mv & 0x80) {	/* stereo */
		int x = sfh.chset[i] & S3M_CH_PAN;
		mod->xxc[i].pan = (x & 0x0f) < 8 ? 0x30 : 0xc0;
	} else {
		mod->xxc[i].pan = 0x80;
	}
    }

    if (sfh.ordnum <= XMP_MAX_MOD_LENGTH) {
	mod->len = sfh.ordnum;
	hio_read(mod->xxo, 1, mod->len, f);
    } else {
	mod->len = XMP_MAX_MOD_LENGTH;
	hio_read(mod->xxo, 1, mod->len, f);
	hio_seek(f, sfh.ordnum - XMP_MAX_MOD_LENGTH, SEEK_CUR);
    }

    mod->pat = -1;
    for (i = 0; i < mod->len && mod->xxo[i] < 0xff; ++i) {
	if (mod->xxo[i] > mod->pat)
            mod->pat = mod->xxo[i];
    }
    mod->pat++;
    if (mod->pat > sfh.patnum)
	mod->pat = sfh.patnum;
    if (mod->pat == 0)
	goto err3;

    mod->trk = mod->pat * mod->chn;
    /* Load and convert header */
    mod->ins = sfh.insnum;
    mod->smp = mod->ins;

    for (i = 0; i < sfh.insnum; i++)
	pp_ins[i] = hio_read16l(f);
 
    for (i = 0; i < sfh.patnum; i++)
	pp_pat[i] = hio_read16l(f);

    /* Default pan positions */

    for (i = 0, sfh.dp -= 0xfc; !sfh.dp /* && n */ && (i < 32); i++) {
	uint8 x = hio_read8(f);
	if (x & S3M_PAN_SET)
	    mod->xxc[i].pan = (x << 4) & 0xff;
	else
	    mod->xxc[i].pan = sfh.mv % 0x80 ? 0x30 + 0xa0 * (i & 1) : 0x80;
    }

    m->c4rate = C4_NTSC_RATE;

    if (sfh.version == 0x1300)
	m->quirk |= QUIRK_VSALL;

#ifndef LIBXMP_CORE_PLAYER
    switch (sfh.version >> 12) {
    case 1:
	snprintf(tracker_name, 40, "Scream Tracker %d.%02x",
		(sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
	m->quirk |= QUIRK_ST3GVOL;
	break;
    case 2:
	snprintf(tracker_name, 40, "Imago Orpheus %d.%02x",
		(sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
	break;
    case 3:
	if (sfh.version == 0x3216) {
		strcpy(tracker_name, "Impulse Tracker 2.14v3");
	} else if (sfh.version == 0x3217) {
		strcpy(tracker_name, "Impulse Tracker 2.14v5");
	} else {
		snprintf(tracker_name, 40, "Impulse Tracker %d.%02x",
			(sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
	}
	break;
    case 5:
	snprintf(tracker_name, 40, "OpenMPT %d.%02x",
		(sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
	break;
    case 4:
	if (sfh.version != 0x4100) {
		snprintf(tracker_name, 40, "Schism Tracker %d.%02x",
			(sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
		break;
	}
	/* fall through */
    case 6:
	snprintf(tracker_name, 40, "BeRoTracker %d.%02x",
		(sfh.version & 0x0f00) >> 8, sfh.version & 0xff);
	break;
    default:
	snprintf(tracker_name, 40, "unknown (%04x)", sfh.version);
    }
示例#6
0
static int coco_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	struct xmp_event *event;
	int i, j;
	int seq_ptr, pat_ptr, smp_ptr[100];

	LOAD_INIT();

	mod->chn = hio_read8(f) & 0x3f;
	libxmp_read_title(f, mod->name, 20);

	for (i = 0; i < 20; i++) {
		if (mod->name[i] == 0x0d)
			mod->name[i] = 0;
	}

	libxmp_set_type(m, "Coconizer");

	mod->ins = mod->smp = hio_read8(f);
	mod->len = hio_read8(f);
	mod->pat = hio_read8(f);
	mod->trk = mod->pat * mod->chn;

	seq_ptr = hio_read32l(f);
	pat_ptr = hio_read32l(f);

	MODULE_INFO();

	if (libxmp_init_instrument(m) < 0)
		return -1;

	m->vol_table = (int *)arch_vol_table;
	m->volbase = 0xff;

	for (i = 0; i < mod->ins; i++) {
		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
			return -1;

		smp_ptr[i] = hio_read32l(f);
		mod->xxs[i].len = hio_read32l(f);
		mod->xxi[i].sub[0].vol = 0xff - hio_read32l(f);
		mod->xxi[i].sub[0].pan = 0x80;
		mod->xxs[i].lps = hio_read32l(f);
                mod->xxs[i].lpe = mod->xxs[i].lps + hio_read32l(f);
		if (mod->xxs[i].lpe)
			mod->xxs[i].lpe -= 1;
		mod->xxs[i].flg = mod->xxs[i].lps > 0 ?  XMP_SAMPLE_LOOP : 0;
		hio_read(mod->xxi[i].name, 1, 11, f);
		for (j = 0; j < 11; j++) {
			if (mod->xxi[i].name[j] == 0x0d)
				mod->xxi[i].name[j] = 0;
		}
		hio_read8(f);	/* unused */
		mod->xxi[i].sub[0].sid = i;

		if (mod->xxs[i].len > 0)
			mod->xxi[i].nsm = 1;

		D_(D_INFO "[%2X] %-10.10s  %05x %05x %05x %c V%02x",
				i, mod->xxi[i].name,
				mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
				mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
				mod->xxi[i].sub[0].vol);
	}

	/* Sequence */

	hio_seek(f, start + seq_ptr, SEEK_SET);
	for (i = 0; ; i++) {
		uint8 x = hio_read8(f);
		if (x == 0xff)
			break;
		mod->xxo[i] = x;
	}
	for (i++; i % 4; i++)	/* for alignment */
		hio_read8(f);


	/* Patterns */

	if (libxmp_init_pattern(mod) < 0)
		return -1;

	D_(D_INFO "Stored patterns: %d", mod->pat);

	for (i = 0; i < mod->pat; i++) {
		if (libxmp_alloc_pattern_tracks(mod, i, 64) < 0)
			return -1;

		for (j = 0; j < (64 * mod->chn); j++) {
			event = &EVENT (i, j % mod->chn, j / mod->chn);
			event->fxp = hio_read8(f);
			event->fxt = hio_read8(f);
			event->ins = hio_read8(f);
			event->note = hio_read8(f);
			if (event->note)
				event->note += 12;

			fix_effect(event);
		}
	}

	/* Read samples */

	D_(D_INFO "Stored samples : %d", mod->smp);

	for (i = 0; i < mod->ins; i++) {
		if (mod->xxi[i].nsm == 0)
			continue;

		hio_seek(f, start + smp_ptr[i], SEEK_SET);
		if (libxmp_load_sample(m, f, SAMPLE_FLAG_VIDC, &mod->xxs[i], NULL) < 0)
			return -1;
	}

	for (i = 0; i < mod->chn; i++) {
		mod->xxc[i].pan = DEFPAN((((i + 3) / 2) % 2) * 0xff);
	}

	return 0;
}
示例#7
0
文件: xm_load.c 项目: GCrean/libxmp
static int load_patterns(struct module_data *m, int version, HIO_HANDLE *f)
{
    struct xmp_module *mod = &m->mod;
    struct xm_pattern_header xph;
    struct xmp_event *event;
    uint8 *patbuf, *pat, b;
    int i, j, r;

    mod->pat++;
    if (pattern_init(mod) < 0)
	return -1;

    D_(D_INFO "Stored patterns: %d", mod->pat - 1);

    /* Endianism fixed by Miodrag Vallat <*****@*****.**>
     * Mon, 04 Jan 1999 11:17:20 +0100
     */
    for (i = 0; i < mod->pat - 1; i++) {
	xph.length = hio_read32l(f);
	xph.packing = hio_read8(f);
	xph.rows = version > 0x0102 ? hio_read16l(f) : hio_read8(f) + 1;
	xph.datasize = hio_read16l(f);

	r = xph.rows;
	if (r == 0)
	    r = 0x100;

	if (pattern_tracks_alloc(mod, i, r) < 0)
	    return -1;

	if (xph.datasize) {
	    pat = patbuf = calloc(1, xph.datasize);
	    if (patbuf == NULL)
		return -1;

	    hio_read(patbuf, 1, xph.datasize, f);
	    for (j = 0; j < (mod->chn * r); j++) {
		if ((pat - patbuf) >= xph.datasize)
		    break;
		event = &EVENT(i, j % mod->chn, j / mod->chn);
		if ((b = *pat++) & XM_EVENT_PACKING) {
		    if (b & XM_EVENT_NOTE_FOLLOWS)
			event->note = *pat++;
		    if (b & XM_EVENT_INSTRUMENT_FOLLOWS)
			event->ins = *pat++;
		    if (b & XM_EVENT_VOLUME_FOLLOWS)
			event->vol = *pat++;
		    if (b & XM_EVENT_FXTYPE_FOLLOWS) {
			event->fxt = *pat++;
#if 0
			if (event->fxt == FX_GLOBALVOL)
			    event->fxt = FX_TRK_VOL;
			if (event->fxt == FX_G_VOLSLIDE)
			    event->fxt = FX_TRK_VSLIDE;
#endif
		    }
		    if (b & XM_EVENT_FXPARM_FOLLOWS)
			event->fxp = *pat++;
		} else {
		    event->note = b;
		    event->ins = *pat++;
		    event->vol = *pat++;
		    event->fxt = *pat++;
		    event->fxp = *pat++;
		}

		if (event->note == 0x61)
		    event->note = XMP_KEY_OFF;
		else if (event->note > 0)
		    event->note += 12;

		if (!event->vol)
		    continue;

		/* Volume set */
		if ((event->vol >= 0x10) && (event->vol <= 0x50)) {
		    event->vol -= 0x0f;
		    continue;
		}
		/* Volume column effects */
		switch (event->vol >> 4) {
		case 0x06:	/* Volume slide down */
		    event->f2t = FX_VOLSLIDE_2;
		    event->f2p = event->vol - 0x60;
		    break;
		case 0x07:	/* Volume slide up */
		    event->f2t = FX_VOLSLIDE_2;
		    event->f2p = (event->vol - 0x70) << 4;
		    break;
		case 0x08:	/* Fine volume slide down */
		    event->f2t = FX_EXTENDED;
		    event->f2p = (EX_F_VSLIDE_DN << 4) | (event->vol - 0x80);
		    break;
		case 0x09:	/* Fine volume slide up */
		    event->f2t = FX_EXTENDED;
		    event->f2p = (EX_F_VSLIDE_UP << 4) | (event->vol - 0x90);
		    break;
		case 0x0a:	/* Set vibrato speed */
		    event->f2t = FX_VIBRATO;
		    event->f2p = (event->vol - 0xa0) << 4;
		    break;
		case 0x0b:	/* Vibrato */
		    event->f2t = FX_VIBRATO;
		    event->f2p = event->vol - 0xb0;
		    break;
		case 0x0c:	/* Set panning */
		    event->f2t = FX_SETPAN;
		    event->f2p = ((event->vol - 0xc0) << 4) + 8;
		    break;
		case 0x0d:	/* Pan slide left */
		    event->f2t = FX_PANSLIDE;
		    event->f2p = (event->vol - 0xd0) << 4;
		    break;
		case 0x0e:	/* Pan slide right */
		    event->f2t = FX_PANSLIDE;
		    event->f2p = event->vol - 0xe0;
		    break;
		case 0x0f:	/* Tone portamento */
		    event->f2t = FX_TONEPORTA;
		    event->f2p = (event->vol - 0xf0) << 4;
		    break;
		}
		event->vol = 0;
	    }
	    free (patbuf);
	}
    }
示例#8
0
static int amf_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	int i, j;
	struct xmp_event *event;
	uint8 buf[1024];
	int *trkmap, newtrk;
	int ver;

	LOAD_INIT();

	hio_read(buf, 1, 3, f);
	ver = hio_read8(f);

	hio_read(buf, 1, 32, f);
	strncpy(mod->name, (char *)buf, 32);
	set_type(m, "DSMI %d.%d AMF", ver / 10, ver % 10);

	mod->ins = hio_read8(f);
	mod->len = hio_read8(f);
	mod->trk = hio_read16l(f);
	mod->chn = hio_read8(f);

	mod->smp = mod->ins;
	mod->pat = mod->len;

	if (ver == 0x0a)
		hio_read(buf, 1, 16, f);	/* channel remap table */

	if (ver >= 0x0d) {
		hio_read(buf, 1, 32, f);	/* panning table */
		for (i = 0; i < 32; i++) {
			mod->xxc->pan = 0x80 + 2 * (int8)buf[i];
		}
		mod->bpm = hio_read8(f);
		mod->spd = hio_read8(f);
	} else if (ver >= 0x0b) {
		hio_read(buf, 1, 16, f);
	}

	MODULE_INFO();
 

	/* Orders */

	/*
	 * Andre Timmermans <*****@*****.**> says:
	 *
	 * Order table: track numbers in this table are not explained,
	 * but as you noticed you have to perform -1 to obtain the index
	 * in the track table. For value 0, found in some files, I think
	 * it means an empty track.
	 */

	for (i = 0; i < mod->len; i++)
		mod->xxo[i] = i;

	D_(D_INFO "Stored patterns: %d", mod->pat);

	mod->xxp = calloc(sizeof(struct xmp_pattern *), mod->pat + 1);
	if (mod->xxp == NULL)
		return -1;

	for (i = 0; i < mod->pat; i++) {
		if (pattern_alloc(mod, i) < 0)
			return -1;

		mod->xxp[i]->rows = ver >= 0x0e ? hio_read16l(f) : 64;

		for (j = 0; j < mod->chn; j++) {
			uint16 t = hio_read16l(f);
			mod->xxp[i]->index[j] = t;
		}
	}

	/* Instruments */

	if (instrument_init(mod) < 0)
		return -1;

	/* Probe for 2-byte loop start 1.0 format
	 * in facing_n.amf and sweetdrm.amf have only the sample
	 * loop start specified in 2 bytes
	 */
	if (ver <= 0x0a) {
		uint8 b;
		uint32 len, start, end;
		long pos = hio_tell(f);
		for (i = 0; i < mod->ins; i++) {
			b = hio_read8(f);
			if (b != 0 && b != 1) {
				ver = 0x09;
				break;
			}
			hio_seek(f, 32 + 13, SEEK_CUR);
			if (hio_read32l(f) > 0x100000) { /* check index */
				ver = 0x09;
				break;
			}
			len = hio_read32l(f);
			if (len > 0x100000) {		/* check len */
				ver = 0x09;
				break;
			}
			if (hio_read16l(f) == 0x0000) {	/* check c2spd */
				ver = 0x09;
				break;
			}
			if (hio_read8(f) > 0x40) {	/* check volume */
				ver = 0x09;
				break;
			}
			start = hio_read32l(f);
			if (start > len) {		/* check loop start */
				ver = 0x09;
				break;
			}
			end = hio_read32l(f);
			if (end > len) {		/* check loop end */
				ver = 0x09;
				break;
			}
		}
		hio_seek(f, pos, SEEK_SET);
	}

	for (i = 0; i < mod->ins; i++) {
		/*uint8 b;*/
		int c2spd;

		if (subinstrument_alloc(mod, i, 1) < 0)
			return -1;

		/*b =*/ hio_read8(f);

		hio_read(buf, 1, 32, f);
		instrument_name(mod, i, buf, 32);

		hio_read(buf, 1, 13, f);	/* sample name */
		hio_read32l(f);			/* sample index */

		mod->xxi[i].nsm = 1;
		mod->xxi[i].sub[0].sid = i;
		mod->xxi[i].sub[0].pan = 0x80;
		mod->xxs[i].len = hio_read32l(f);
		c2spd = hio_read16l(f);
		c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
		mod->xxi[i].sub[0].vol = hio_read8(f);

		/*
		 * Andre Timmermans <*****@*****.**> says:
		 *
		 * [Miodrag Vallat's] doc tells that in version 1.0 only
		 * sample loop start is present (2 bytes) but the files I
		 * have tells both start and end are present (2*4 bytes).
		 * Maybe it should be read as version < 1.0.
		 *
		 * CM: confirmed with Maelcum's "The tribal zone"
		 */

		if (ver < 0x0a) {
			mod->xxs[i].lps = hio_read16l(f);
			mod->xxs[i].lpe = mod->xxs[i].len;
		} else {
			mod->xxs[i].lps = hio_read32l(f);
			mod->xxs[i].lpe = hio_read32l(f);
		}

		if (ver < 0x0a) {
			mod->xxs[i].flg = mod->xxs[i].lps > 0 ? XMP_SAMPLE_LOOP : 0;
		} else {
			mod->xxs[i].flg = mod->xxs[i].lpe > mod->xxs[i].lps ?
							XMP_SAMPLE_LOOP : 0;
		}

		D_(D_INFO "[%2X] %-32.32s %05x %05x %05x %c V%02x %5d",
			i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps,
			mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ?
			'L' : ' ', mod->xxi[i].sub[0].vol, c2spd);
	}
				

	/* Tracks */

	trkmap = calloc(sizeof(int), mod->trk);
	if (trkmap == NULL)
		return -1;
	newtrk = 0;

	for (i = 0; i < mod->trk; i++) {		/* read track table */
		uint16 t;
		t = hio_read16l(f);
		trkmap[i] = t;
		if (t > newtrk) newtrk = t;
/*printf("%d -> %d\n", i, t);*/
	}

	for (i = 0; i < mod->pat; i++) {		/* read track table */
		for (j = 0; j < mod->chn; j++) {
			int k = mod->xxp[i]->index[j] - 1;

			/* Use empty track if an invalid track is requested
			 * (such as in Lasse Makkonen "faster and louder")
			 */
			if (k < 0 || k >= mod->trk)
				k = 0;
			mod->xxp[i]->index[j] = trkmap[k];
/*printf("mod->xxp[%d]->info[%d].index = %d (k = %d)\n", i, j, trkmap[k], k);*/
		}
	}

	mod->trk = newtrk;		/* + empty track */
	free(trkmap);

	D_(D_INFO "Stored tracks: %d", mod->trk);

	mod->trk++;
	mod->xxt = calloc (sizeof (struct xmp_track *), mod->trk);
	if (mod->xxt == NULL)
		return -1;

	/* Alloc track 0 as empty track */
	if (track_alloc(mod, 0, 64) < 0)
		return -1;

	/* Alloc rest of the tracks */
	for (i = 1; i < mod->trk; i++) {
		uint8 t1, t2, t3;
		int size;

		if (track_alloc(mod, i, 64) < 0)
			return -1;

		size = hio_read24l(f);
/*printf("TRACK %d SIZE %d\n", i, size);*/

		for (j = 0; j < size; j++) {
			t1 = hio_read8(f);			/* row */
			t2 = hio_read8(f);			/* type */
			t3 = hio_read8(f);			/* parameter */
/*printf("track %d row %d: %02x %02x %02x\n", i, t1, t1, t2, t3);*/

			if (t1 == 0xff && t2 == 0xff && t3 == 0xff)
				break;

			event = &mod->xxt[i]->event[t1];

			if (t2 < 0x7f) {		/* note */
				if (t2 > 0)
					event->note = t2 + 1;
				event->vol = t3;
			} else if (t2 == 0x7f) {	/* copy previous */
				memcpy(event, &mod->xxt[i]->event[t1 - 1],
					sizeof(struct xmp_event));
			} else if (t2 == 0x80) {	/* instrument */
				event->ins = t3 + 1;
			} else  {			/* effects */
				uint8 fxp, fxt;

				fxp = fxt = 0;

				switch (t2) {
				case 0x81:
					fxt = FX_SPEED;
					fxp = t3;
					break;
				case 0x82:
					if ((int8)t3 > 0) {
						fxt = FX_VOLSLIDE;
						fxp = t3 << 4;
					} else {
						fxt = FX_VOLSLIDE;
						fxp = -(int8)t3 & 0x0f;
					}
					break;
				case 0x83:
					event->vol = t3;
					break;
				case 0x84:
					/* AT: Not explained for 0x84, pitch
					 * slide, value 0x00 corresponds to
					 * S3M E00 and 0x80 stands for S3M F00
					 * (I checked with M2AMF)
					 */
					if ((int8)t3 >= 0) {
						fxt = FX_PORTA_DN;
						fxp = t3;
					} else if (t3 == 0x80) {
						fxt = FX_PORTA_UP;
						fxp = 0;
					} else {
						fxt = FX_PORTA_UP;
						fxp = -(int8)t3;
					}
					break;
				case 0x85:
					/* porta abs -- unknown */
					break;
				case 0x86:
					fxt = FX_TONEPORTA;
					fxp = t3;
					break;

				/* AT: M2AMF maps both tremolo and tremor to
				 * 0x87. Since tremor is only found in certain
				 * formats, maybe it would be better to
				 * consider it is a tremolo.
				 */
				case 0x87:
					fxt = FX_TREMOLO;
					fxp = t3;
					break;
				case 0x88:
					fxt = FX_ARPEGGIO;
					fxp = t3;
					break;
				case 0x89:
					fxt = FX_VIBRATO;
					fxp = t3;
					break;
				case 0x8a:
					if ((int8)t3 > 0) {
						fxt = FX_TONE_VSLIDE;
						fxp = t3 << 4;
					} else {
						fxt = FX_TONE_VSLIDE;
						fxp = -(int8)t3 & 0x0f;
					}
					break;
				case 0x8b:
					if ((int8)t3 > 0) {
						fxt = FX_VIBRA_VSLIDE;
						fxp = t3 << 4;
					} else {
						fxt = FX_VIBRA_VSLIDE;
						fxp = -(int8)t3 & 0x0f;
					}
					break;
				case 0x8c:
					fxt = FX_BREAK;
					fxp = t3;
					break;
				case 0x8d:
					fxt = FX_JUMP;
					fxp = t3;
					break;
				case 0x8e:
					/* sync -- unknown */
					break;
				case 0x8f:
					fxt = FX_EXTENDED;
					fxp = (EX_RETRIG << 4) | (t3 & 0x0f);
					break;
				case 0x90:
					fxt = FX_OFFSET;
					fxp = t3;
					break;
				case 0x91:
					if ((int8)t3 > 0) {
						fxt = FX_EXTENDED;
						fxp = (EX_F_VSLIDE_UP << 4) |
							(t3 & 0x0f);
					} else {
						fxt = FX_EXTENDED;
						fxp = (EX_F_VSLIDE_DN << 4) |
							(t3 & 0x0f);
					}
					break;
				case 0x92:
					if ((int8)t3 > 0) {
						fxt = FX_PORTA_DN;
						fxp = 0xf0 | (fxp & 0x0f);
					} else {
						fxt = FX_PORTA_UP;
						fxp = 0xf0 | (fxp & 0x0f);
					}
					break;
				case 0x93:
					fxt = FX_EXTENDED;
					fxp = (EX_DELAY << 4) | (t3 & 0x0f);
					break;
				case 0x94:
					fxt = FX_EXTENDED;
					fxp = (EX_CUT << 4) | (t3 & 0x0f);
					break;
				case 0x95:
					fxt = FX_SPEED;
					if (t3 < 0x21)
						t3 = 0x21;
					fxp = t3;
					break;
				case 0x96:
					if ((int8)t3 > 0) {
						fxt = FX_PORTA_DN;
						fxp = 0xe0 | (fxp & 0x0f);
					} else {
						fxt = FX_PORTA_UP;
						fxp = 0xe0 | (fxp & 0x0f);
					}
					break;
				case 0x97:
					fxt = FX_SETPAN;
					fxp = 0x80 + 2 * (int8)t3;
					break;
				}

				event->fxt = fxt;
				event->fxp = fxp;
			}

		}
	}


	/* Samples */

	D_(D_INFO "Stored samples: %d", mod->smp);

	for (i = 0; i < mod->ins; i++) {
		if (load_sample(m, f, SAMPLE_FLAG_UNS, &mod->xxs[i], NULL) < 0)
			return -1;
	}

	m->quirk |= QUIRK_FINEFX;

	return 0;
}
示例#9
0
文件: far_load.c 项目: Nlcke/gideros
static int far_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
    struct xmp_module *mod = &m->mod;
    int i, j, vib = 0;
    struct xmp_event *event;
    struct far_header ffh;
    struct far_header2 ffh2;
    struct far_instrument fih;
    uint8 sample_map[8];

    LOAD_INIT();

    hio_read32b(f);			/* File magic: 'FAR\xfe' */
    hio_read(&ffh.name, 40, 1, f);	/* Song name */
    hio_read(&ffh.crlf, 3, 1, f);	/* 0x0d 0x0a 0x1A */
    ffh.headersize = hio_read16l(f);	/* Remaining header size in bytes */
    ffh.version = hio_read8(f);		/* Version MSN=major, LSN=minor */
    hio_read(&ffh.ch_on, 16, 1, f);	/* Channel on/off switches */
    hio_seek(f, 9, SEEK_CUR);		/* Current editing values */
    ffh.tempo = hio_read8(f);		/* Default tempo */
    hio_read(&ffh.pan, 16, 1, f);	/* Channel pan definitions */
    hio_read32l(f);			/* Grid, mode (for editor) */
    ffh.textlen = hio_read16l(f);	/* Length of embedded text */

    /* Sanity check */
    if (ffh.tempo == 0) {
	return -1;
    }

    hio_seek(f, ffh.textlen, SEEK_CUR);	/* Skip song text */

    hio_read(&ffh2.order, 256, 1, f);	/* Orders */
    ffh2.patterns = hio_read8(f);	/* Number of stored patterns (?) */
    ffh2.songlen = hio_read8(f);	/* Song length in patterns */
    ffh2.restart = hio_read8(f);	/* Restart pos */
    for (i = 0; i < 256; i++) {
	ffh2.patsize[i] = hio_read16l(f); /* Size of each pattern in bytes */
    }

    mod->chn = 16;
    /*mod->pat=ffh2.patterns; (Error in specs? --claudio) */
    mod->len = ffh2.songlen;
    mod->spd = 6;
    mod->bpm = 8 * 60 / ffh.tempo;
    memcpy (mod->xxo, ffh2.order, mod->len);

    for (mod->pat = i = 0; i < 256; i++) {
	if (ffh2.patsize[i])
	    mod->pat = i + 1;
    }

    mod->trk = mod->chn * mod->pat;

    strncpy(mod->name, (char *)ffh.name, 40);
    set_type(m, "Farandole Composer %d.%d", MSN(ffh.version), LSN(ffh.version));

    MODULE_INFO();

    if (pattern_init(mod) < 0)
	return -1;

    /* Read and convert patterns */
    D_(D_INFO "Comment bytes  : %d", ffh.textlen);
    D_(D_INFO "Stored patterns: %d", mod->pat);

    for (i = 0; i < mod->pat; i++) {
	uint8 brk, note, ins, vol, fxb;
	int rows;

	if (pattern_alloc(mod, i) < 0)
	    return -1;

	if (!ffh2.patsize[i])
	    continue;

	rows = (ffh2.patsize[i] - 2) / 64;

	/* Sanity check */
	if (rows <= 0 || rows > 256) {
	    return -1;
	}

	mod->xxp[i]->rows = rows;

	if (tracks_in_pattern_alloc(mod, i) < 0)
	    return -1;

	brk = hio_read8(f) + 1;
	hio_read8(f);

	for (j = 0; j < mod->xxp[i]->rows * mod->chn; j++) {
	    event = &EVENT(i, j % mod->chn, j / mod->chn);

	    if ((j % mod->chn) == 0 && (j / mod->chn) == brk)
		event->f2t = FX_BREAK;
	
	    note = hio_read8(f);
	    ins = hio_read8(f);
	    vol = hio_read8(f);
	    fxb = hio_read8(f);

	    if (note)
		event->note = note + 48;
	    if (event->note || ins)
		event->ins = ins + 1;

	    vol = 16 * LSN(vol) + MSN(vol);

	    if (vol)
		event->vol = vol - 0x10;	/* ? */

	    event->fxt = fx[MSN(fxb)];
	    event->fxp = LSN(fxb);

	    switch (event->fxt) {
	    case NONE:
	        event->fxt = event->fxp = 0;
		break;
	    case FX_FAR_PORTA_UP:
		event->fxt = FX_EXTENDED;
		event->fxp |= (EX_F_PORTA_UP << 4);
		break;
	    case FX_FAR_PORTA_DN:
		event->fxt = FX_EXTENDED;
		event->fxp |= (EX_F_PORTA_DN << 4);
		break;
	    case FX_FAR_RETRIG:
		event->fxt = FX_EXTENDED;
		event->fxp |= (EX_RETRIG << 4);
		break;
	    case FX_FAR_DELAY:
		event->fxt = FX_EXTENDED;
		event->fxp |= (EX_DELAY << 4);
		break;
	    case FX_FAR_SETVIBRATO:
		vib = event->fxp & 0x0f;
		event->fxt = event->fxp = 0;
		break;
	    case FX_VIBRATO:
		event->fxp = (event->fxp << 4) + vib;
		break;
	    case FX_PER_VIBRATO:
		event->fxp = (event->fxp << 4) + vib;
		break;
	    case FX_FAR_VSLIDE_UP:	/* Fine volume slide up */
		event->fxt = FX_EXTENDED;
		event->fxp |= (EX_F_VSLIDE_UP << 4);
		break;
	    case FX_FAR_VSLIDE_DN:	/* Fine volume slide down */
		event->fxt = FX_EXTENDED;
		event->fxp |= (EX_F_VSLIDE_DN << 4);
		break;
	    case FX_SPEED:
		if (event->fxp != 0) {
			event->fxp = 8 * 60 / event->fxp;
		} else {
			event->fxt = 0;
		}
		break;
	    }
	}
    }

    mod->ins = -1;
    hio_read(sample_map, 1, 8, f);
    for (i = 0; i < 64; i++) {
	if (sample_map[i / 8] & (1 << (i % 8)))
		mod->ins = i;
    }
    mod->ins++;

    mod->smp = mod->ins;

    if (instrument_init(mod) < 0)
	return -1;

    /* Read and convert instruments and samples */

    for (i = 0; i < mod->ins; i++) {
	if (!(sample_map[i / 8] & (1 << (i % 8))))
		continue;

	if (subinstrument_alloc(mod, i, 1) < 0)
	    return -1;

	hio_read(&fih.name, 32, 1, f);	/* Instrument name */
	fih.length = hio_read32l(f);	/* Length of sample (up to 64Kb) */
	fih.finetune = hio_read8(f);	/* Finetune (unsuported) */
	fih.volume = hio_read8(f);	/* Volume (unsuported?) */
	fih.loop_start = hio_read32l(f);/* Loop start */
	fih.loopend = hio_read32l(f);	/* Loop end */
	fih.sampletype = hio_read8(f);	/* 1=16 bit sample */
	fih.loopmode = hio_read8(f);

	/* Sanity check */
	if (fih.length > 0x10000 || fih.loop_start > 0x10000 ||
            fih.loopend > 0x10000) {
		return -1;
	}

	mod->xxs[i].len = fih.length;
	mod->xxs[i].lps = fih.loop_start;
	mod->xxs[i].lpe = fih.loopend;
	mod->xxs[i].flg = 0;

	if (mod->xxs[i].len > 0)
		mod->xxi[i].nsm = 1;

	if (fih.sampletype != 0) {
		mod->xxs[i].flg |= XMP_SAMPLE_16BIT;
		mod->xxs[i].len >>= 1;
		mod->xxs[i].lps >>= 1;
		mod->xxs[i].lpe >>= 1;
	}

	mod->xxs[i].flg |= fih.loopmode ? XMP_SAMPLE_LOOP : 0;
	mod->xxi[i].sub[0].vol = 0xff; /* fih.volume; */
	mod->xxi[i].sub[0].sid = i;

	instrument_name(mod, i, fih.name, 32);

	D_(D_INFO "[%2X] %-32.32s %04x %04x %04x %c V%02x",
		i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps,
		mod->xxs[i].lpe, fih.loopmode ? 'L' : ' ', mod->xxi[i].sub[0].vol);

	if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
		return -1;
    }
示例#10
0
static int gdm_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	struct xmp_event *event;
	int vermaj, vermin, tvmaj, tvmin, tracker;
	int /*origfmt,*/ ord_ofs, pat_ofs, ins_ofs, smp_ofs;
	uint8 buffer[32], panmap[32];
	int i;

	LOAD_INIT();

	hio_read32b(f);			/* skip magic */
	hio_read(mod->name, 1, 32, f);
	hio_seek(f, 32, SEEK_CUR);	/* skip author */

	hio_seek(f, 7, SEEK_CUR);

	vermaj = hio_read8(f);
	vermin = hio_read8(f);
	tracker = hio_read16l(f);
	tvmaj = hio_read8(f);
	tvmin = hio_read8(f);

	if (tracker == 0) {
		libxmp_set_type(m, "GDM %d.%02d (2GDM %d.%02d)",
					vermaj, vermin, tvmaj, tvmin);
	} else {
		libxmp_set_type(m, "GDM %d.%02d (unknown tracker %d.%02d)",
					vermaj, vermin, tvmaj, tvmin);
	}

	hio_read(panmap, 32, 1, f);
	for (i = 0; i < 32; i++) {
		if (panmap[i] == 255) {
			panmap[i] = 8;
			mod->xxc[i].vol = 0;
			mod->xxc[i].flg |= XMP_CHANNEL_MUTE;
		} else if (panmap[i] == 16) {
			panmap[i] = 8;
		}
		mod->xxc[i].pan = 0x80 + (panmap[i] - 8) * 16;
	}

	mod->gvl = hio_read8(f);
	mod->spd = hio_read8(f);
	mod->bpm = hio_read8(f);
	/*origfmt =*/ hio_read16l(f);
	ord_ofs = hio_read32l(f);
	mod->len = hio_read8(f) + 1;
	pat_ofs = hio_read32l(f);
	mod->pat = hio_read8(f) + 1;
	ins_ofs = hio_read32l(f);
	smp_ofs = hio_read32l(f);
	mod->ins = mod->smp = hio_read8(f) + 1;
	
	m->c4rate = C4_NTSC_RATE;

	MODULE_INFO();

	hio_seek(f, start + ord_ofs, SEEK_SET);

	for (i = 0; i < mod->len; i++)
		mod->xxo[i] = hio_read8(f);

	/* Read instrument data */

	hio_seek(f, start + ins_ofs, SEEK_SET);

	if (libxmp_init_instrument(m) < 0)
		return -1;

	for (i = 0; i < mod->ins; i++) {
		int flg, c4spd, vol, pan;

		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
			return -1;

		if (hio_read(buffer, 1, 32, f) != 32)
			return -1;

		libxmp_instrument_name(mod, i, buffer, 32);
		hio_seek(f, 12, SEEK_CUR);		/* skip filename */
		hio_read8(f);			/* skip EMS handle */
		mod->xxs[i].len = hio_read32l(f);
		mod->xxs[i].lps = hio_read32l(f);
		mod->xxs[i].lpe = hio_read32l(f);
		flg = hio_read8(f);
		c4spd = hio_read16l(f);
		vol = hio_read8(f);
		pan = hio_read8(f);
		
		mod->xxi[i].sub[0].vol = vol > 0x40 ? 0x40 : vol;
		mod->xxi[i].sub[0].pan = pan > 15 ? 0x80 : 0x80 + (pan - 8) * 16;
		libxmp_c2spd_to_note(c4spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);

		mod->xxi[i].sub[0].sid = i;
		mod->xxs[i].flg = 0;


		if (mod->xxs[i].len > 0)
			mod->xxi[i].nsm = 1;

		if (flg & 0x01) {
			mod->xxs[i].flg |= XMP_SAMPLE_LOOP;
		}
		if (flg & 0x02) {
			mod->xxs[i].flg |= XMP_SAMPLE_16BIT;
			mod->xxs[i].len >>= 1;
			mod->xxs[i].lps >>= 1;
			mod->xxs[i].lpe >>= 1;
		}

		D_(D_INFO "[%2X] %-32.32s %05x%c%05x %05x %c V%02x P%02x %5d",
				i, mod->xxi[i].name,
				mod->xxs[i].len,
				mod->xxs[i].flg & XMP_SAMPLE_16BIT ? '+' : ' ',
				mod->xxs[i].lps,
				mod->xxs[i].lpe,
				mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
				mod->xxi[i].sub[0].vol,
				mod->xxi[i].sub[0].pan,
				c4spd);
	}
示例#11
0
static int stx_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
    struct xmp_module *mod = &m->mod;
    int c, r, i, broken = 0;
    struct xmp_event *event = 0, dummy;
    struct stx_file_header sfh;
    struct stx_instrument_header sih;
    uint8 n, b;
    uint16 x16;
    int bmod2stm = 0;
    uint16 *pp_ins;		/* Parapointers to instruments */
    uint16 *pp_pat;		/* Parapointers to patterns */

    LOAD_INIT();

    hio_read(&sfh.name, 20, 1, f);
    hio_read(&sfh.magic, 8, 1, f);
    sfh.psize = hio_read16l(f);
    sfh.unknown1 = hio_read16l(f);
    sfh.pp_pat = hio_read16l(f);
    sfh.pp_ins = hio_read16l(f);
    sfh.pp_chn = hio_read16l(f);
    sfh.unknown2 = hio_read16l(f);
    sfh.unknown3 = hio_read16l(f);
    sfh.gvol = hio_read8(f);
    sfh.tempo = hio_read8(f);
    sfh.unknown4 = hio_read16l(f);
    sfh.unknown5 = hio_read16l(f);
    sfh.patnum = hio_read16l(f);
    sfh.insnum = hio_read16l(f);
    sfh.ordnum = hio_read16l(f);
    sfh.unknown6 = hio_read16l(f);
    sfh.unknown7 = hio_read16l(f);
    sfh.unknown8 = hio_read16l(f);
    hio_read(&sfh.magic2, 4, 1, f);

    /* Sanity check */
    if (sfh.patnum > 254 || sfh.insnum > 256 || sfh.ordnum > 256)
	return -1;

    /* BMOD2STM does not convert pitch */
    if (!strncmp ((char *) sfh.magic, "BMOD2STM", 8))
	bmod2stm = 1;

#if 0
    if ((strncmp ((char *) sfh.magic, "!Scream!", 8) &&
	!bmod2stm) || strncmp ((char *) sfh.magic2, "SCRM", 4))
	return -1;
#endif

    mod->ins = sfh.insnum;
    mod->pat = sfh.patnum;
    mod->trk = mod->pat * mod->chn;
    mod->len = sfh.ordnum;
    mod->spd = MSN (sfh.tempo);
    mod->smp = mod->ins;
    m->c4rate = C4_NTSC_RATE;

    /* STM2STX 1.0 released with STMIK 0.2 converts STMs with the pattern
     * length encoded in the first two bytes of the pattern (like S3M).
     */
    hio_seek(f, start + (sfh.pp_pat << 4), SEEK_SET);
    x16 = hio_read16l(f);
    hio_seek(f, start + (x16 << 4), SEEK_SET);
    x16 = hio_read16l(f);
    if (x16 == sfh.psize)
	broken = 1;

    strncpy(mod->name, (char *)sfh.name, 20);
    if (bmod2stm)
	set_type(m, "BMOD2STM STX");
    else
	snprintf(mod->type, XMP_NAME_SIZE, "STM2STX 1.%d", broken ? 0 : 1);

    MODULE_INFO();
 
    pp_pat = calloc (2, mod->pat);
    if (pp_pat == NULL)
	goto err;

    pp_ins = calloc (2, mod->ins);
    if (pp_ins == NULL)
	goto err2;

    /* Read pattern pointers */
    hio_seek(f, start + (sfh.pp_pat << 4), SEEK_SET);
    for (i = 0; i < mod->pat; i++)
	pp_pat[i] = hio_read16l(f);

    /* Read instrument pointers */
    hio_seek(f, start + (sfh.pp_ins << 4), SEEK_SET);
    for (i = 0; i < mod->ins; i++)
	pp_ins[i] = hio_read16l(f);

    /* Skip channel table (?) */
    hio_seek(f, start + (sfh.pp_chn << 4) + 32, SEEK_SET);

    /* Read orders */
    for (i = 0; i < mod->len; i++) {
	mod->xxo[i] = hio_read8(f);
	hio_seek(f, 4, SEEK_CUR);
    }
 
    if (instrument_init(mod) < 0)
	goto err3;

    /* Read and convert instruments and samples */

    for (i = 0; i < mod->ins; i++) {
	if (subinstrument_alloc(mod, i, 1) < 0)
	    goto err3;

	hio_seek(f, start + (pp_ins[i] << 4), SEEK_SET);

	sih.type = hio_read8(f);
	hio_read(&sih.dosname, 13, 1, f);
	sih.memseg = hio_read16l(f);
	sih.length = hio_read32l(f);
	sih.loopbeg = hio_read32l(f);
	sih.loopend = hio_read32l(f);
	sih.vol = hio_read8(f);
	sih.rsvd1 = hio_read8(f);
	sih.pack = hio_read8(f);
	sih.flags = hio_read8(f);
	sih.c2spd = hio_read16l(f);
	sih.rsvd2 = hio_read16l(f);
	hio_read(&sih.rsvd3, 4, 1, f);
	sih.int_gp = hio_read16l(f);
	sih.int_512 = hio_read16l(f);
	sih.int_last = hio_read32l(f);
	hio_read(&sih.name, 28, 1, f);
	hio_read(&sih.magic, 4, 1, f);

	mod->xxs[i].len = sih.length;
	mod->xxs[i].lps = sih.loopbeg;
	mod->xxs[i].lpe = sih.loopend;
	if (mod->xxs[i].lpe == 0xffff)
	    mod->xxs[i].lpe = 0;
	mod->xxs[i].flg = mod->xxs[i].lpe > 0 ? XMP_SAMPLE_LOOP : 0;
	mod->xxi[i].sub[0].vol = sih.vol;
	mod->xxi[i].sub[0].pan = 0x80;
	mod->xxi[i].sub[0].sid = i;
	mod->xxi[i].nsm = 1;

	instrument_name(mod, i, sih.name, 12);

	D_(D_INFO "[%2X] %-14.14s %04x %04x %04x %c V%02x %5d\n", i,
		mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps, mod->xxs[i].lpe,
		mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
		mod->xxi[i].sub[0].vol, sih.c2spd);

	sih.c2spd = 8363 * sih.c2spd / 8448;
	c2spd_to_note(sih.c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
    }

    if (pattern_init(mod) < 0)
	goto err3;

    /* Read and convert patterns */
    D_(D_INFO "Stored patterns: %d", mod->pat);

    for (i = 0; i < mod->pat; i++) {
	if (pattern_tracks_alloc(mod, i, 64) < 0)
	    goto err3;

	if (pp_pat[i] == 0)
	    continue;

	hio_seek(f, start + (pp_pat[i] << 4), SEEK_SET);
	if (broken)
	    hio_seek(f, 2, SEEK_CUR);

	for (r = 0; r < 64; ) {
	    b = hio_read8(f);

	    if (b == S3M_EOR) {
		r++;
		continue;
	    }

	    c = b & S3M_CH_MASK;
	    event = c >= mod->chn ? &dummy : &EVENT (i, c, r);

	    if (b & S3M_NI_FOLLOW) {
		n = hio_read8(f);

		switch (n) {
		case 255:
		    n = 0;
		    break;	/* Empty note */
		case 254:
		    n = XMP_KEY_OFF;
		    break;	/* Key off */
		default:
		    n = 37 + 12 * MSN (n) + LSN (n);
		}

		event->note = n;
		event->ins = hio_read8(f);;
	    }

	    if (b & S3M_VOL_FOLLOWS) {
		event->vol = hio_read8(f) + 1;
	    }

	    if (b & S3M_FX_FOLLOWS) {
		event->fxt = fx[hio_read8(f)];
		event->fxp = hio_read8(f);
		switch (event->fxt) {
		case FX_SPEED:
		    event->fxp = MSN (event->fxp);
		    break;
		case FX_NONE:
		    event->fxp = event->fxt = 0;
		    break;
		}
	    }
	}
    }

    free (pp_ins);
    free (pp_pat);

    /* Read samples */
    D_(D_INFO "Stored samples: %d", mod->smp);

    for (i = 0; i < mod->ins; i++) {
	if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
	    goto err;
    }

    m->quirk |= QUIRK_VSALL | QUIRKS_ST3;
    m->read_event_type = READ_EVENT_ST3;

    return 0;

  err3:
    free(pp_ins);
  err2:
    free(pp_pat);
  err:
    return -1;
}
示例#12
0
文件: mtm_load.c 项目: GCrean/libxmp
static int mtm_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
    struct xmp_module *mod = &m->mod;
    int i, j;
    struct mtm_file_header mfh;
    struct mtm_instrument_header mih;
    uint8 mt[192];
    uint16 mp[32];

    LOAD_INIT();

    hio_read(&mfh.magic, 3, 1, f);	/* "MTM" */
    mfh.version = hio_read8(f);		/* MSN=major, LSN=minor */
    hio_read(&mfh.name, 20, 1, f);	/* ASCIIZ Module name */
    mfh.tracks = hio_read16l(f);	/* Number of tracks saved */
    mfh.patterns = hio_read8(f);	/* Number of patterns saved */
    mfh.modlen = hio_read8(f);		/* Module length */
    mfh.extralen = hio_read16l(f);	/* Length of the comment field */
    mfh.samples = hio_read8(f);		/* Number of samples */
    mfh.attr = hio_read8(f);		/* Always zero */
    mfh.rows = hio_read8(f);		/* Number rows per track */
    mfh.channels = hio_read8(f);	/* Number of tracks per pattern */
    hio_read(&mfh.pan, 32, 1, f);	/* Pan positions for each channel */

#if 0
    if (strncmp ((char *)mfh.magic, "MTM", 3))
	return -1;
#endif

    mod->trk = mfh.tracks + 1;
    mod->pat = mfh.patterns + 1;
    mod->len = mfh.modlen + 1;
    mod->ins = mfh.samples;
    mod->smp = mod->ins;
    mod->chn = mfh.channels;
    mod->spd = 6;
    mod->bpm = 125;

    strncpy(mod->name, (char *)mfh.name, 20);
    set_type(m, "MultiTracker %d.%02d MTM", MSN(mfh.version), LSN(mfh.version));

    MODULE_INFO();

    if (instrument_init(mod) < 0)
	return -1;

    /* Read and convert instruments */
    for (i = 0; i < mod->ins; i++) {
	if (subinstrument_alloc(mod, i, 1) < 0)
	    return -1;

	hio_read(&mih.name, 22, 1, f);		/* Instrument name */
	mih.length = hio_read32l(f);		/* Instrument length in bytes */
	mih.loop_start = hio_read32l(f);	/* Sample loop start */
	mih.loopend = hio_read32l(f);		/* Sample loop end */
	mih.finetune = hio_read8(f);		/* Finetune */
	mih.volume = hio_read8(f);		/* Playback volume */
	mih.attr = hio_read8(f);		/* &0x01: 16bit sample */

	mod->xxs[i].len = mih.length;
	mod->xxs[i].lps = mih.loop_start;
	mod->xxs[i].lpe = mih.loopend;
	mod->xxs[i].flg = mod->xxs[i].lpe ? XMP_SAMPLE_LOOP : 0;	/* 1 == Forward loop */
	if (mfh.attr & 1) {
	    mod->xxs[i].flg |= XMP_SAMPLE_16BIT;
	    mod->xxs[i].len >>= 1;
	    mod->xxs[i].lps >>= 1;
	    mod->xxs[i].lpe >>= 1;
	}

	mod->xxi[i].sub[0].vol = mih.volume;
	mod->xxi[i].sub[0].fin = mih.finetune;
	mod->xxi[i].sub[0].pan = 0x80;
	mod->xxi[i].sub[0].sid = i;

	instrument_name(mod, i, mih.name, 22);

	if (mod->xxs[i].len > 0)
		mod->xxi[i].nsm = 1;

	D_(D_INFO "[%2X] %-22.22s %04x%c%04x %04x %c V%02x F%+03d\n", i,
		mod->xxi[i].name, mod->xxs[i].len,
		mod->xxs[i].flg & XMP_SAMPLE_16BIT ? '+' : ' ',
		mod->xxs[i].lps, mod->xxs[i].lpe,
		mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
		mod->xxi[i].sub[0].vol, mod->xxi[i].sub[0].fin - 0x80);
    }
示例#13
0
static int it_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
    struct xmp_module *mod = &m->mod;
    int r, c, i, j, k, pat_len;
    struct xmp_event *event, dummy, lastevent[L_CHANNELS];
    struct it_file_header ifh;
    struct it_instrument1_header i1h;
    struct it_instrument2_header i2h;
    struct it_sample_header ish;
    struct it_envelope env;
    uint8 b, mask[L_CHANNELS];
    int max_ch;
    int inst_map[120], inst_rmap[XMP_MAX_KEYS];
#ifndef LIBXMP_CORE_PLAYER
    char tracker_name[40];
#endif
    uint32 *pp_ins;		/* Pointers to instruments */
    uint32 *pp_smp;		/* Pointers to samples */
    uint32 *pp_pat;		/* Pointers to patterns */
    uint8 last_fxp[64];
    int dca2nna[] = { 0, 2, 3 };
    int new_fx;

    LOAD_INIT();

    /* Load and convert header */
    hio_read32b(f);		/* magic */

    hio_read(&ifh.name, 26, 1, f);
    ifh.hilite_min = hio_read8(f);
    ifh.hilite_maj = hio_read8(f);

    ifh.ordnum = hio_read16l(f);
    ifh.insnum = hio_read16l(f);
    ifh.smpnum = hio_read16l(f);
    ifh.patnum = hio_read16l(f);

    ifh.cwt = hio_read16l(f);
    ifh.cmwt = hio_read16l(f);
    ifh.flags = hio_read16l(f);
    ifh.special = hio_read16l(f);

    ifh.gv = hio_read8(f);
    ifh.mv = hio_read8(f);
    ifh.is = hio_read8(f);
    ifh.it = hio_read8(f);
    ifh.sep = hio_read8(f);
    ifh.pwd = hio_read8(f);

    ifh.msglen = hio_read16l(f);
    ifh.msgofs = hio_read32l(f);
    ifh.rsvd = hio_read32l(f);

    hio_read(&ifh.chpan, 64, 1, f);
    hio_read(&ifh.chvol, 64, 1, f);

    strncpy(mod->name, (char *)ifh.name, XMP_NAME_SIZE);
    mod->len = ifh.ordnum;
    mod->ins = ifh.insnum;
    mod->smp = ifh.smpnum;
    mod->pat = ifh.patnum;

    if (mod->ins) {
        pp_ins = calloc(4, mod->ins);
        if (pp_ins == NULL)
	    goto err;
    } else {
	pp_ins = NULL;
    }

    pp_smp = calloc(4, mod->smp);
    if (pp_smp == NULL)
	goto err2;

    pp_pat = calloc(4, mod->pat);
    if (pp_pat == NULL)
	goto err3;

    mod->spd = ifh.is;
    mod->bpm = ifh.it;

    if (ifh.flags & IT_LINEAR_FREQ) {
       m->quirk |= QUIRK_LINEAR;
    }

    if ((ifh.flags & IT_USE_INST) && ifh.cmwt >= 0x200) {
       m->quirk |= QUIRK_INSVOL;
    }

    for (i = 0; i < 64; i++) {
	struct xmp_channel *xxc = &mod->xxc[i];

	if (ifh.chpan[i] == 100)	/* Surround -> center */
	    ifh.chpan[i] = 32;

	if (ifh.chpan[i] & 0x80) {	/* Channel mute */
	    ifh.chvol[i] = 0;
	    mod->xxc[i].flg |= XMP_CHANNEL_MUTE;
	}

	if (ifh.flags & IT_STEREO) {
	    xxc->pan = (int)ifh.chpan[i] * 0x80 >> 5;
	    if (xxc->pan > 0xff)
		xxc->pan = 0xff;
	} else {
示例#14
0
文件: smix.c 项目: visy/turha
int xmp_smix_load_sample(xmp_context opaque, int num, char *path)
{
	struct context_data *ctx = (struct context_data *)opaque;
	struct smix_data *smix = &ctx->smix;
	struct module_data *m = &ctx->m;
	struct xmp_instrument *xxi;
	struct xmp_sample *xxs;
	HIO_HANDLE *h;
	uint32 magic;
	int chn, rate, bits, size;
	int retval = -XMP_ERROR_INTERNAL;

	if (num >= smix->ins) {
		retval = -XMP_ERROR_INVALID;
		goto err;
	}

	xxi = &smix->xxi[num];
	xxs = &smix->xxs[num];

	h = hio_open_file(path, "rb");
	if (h == NULL) {
		retval = -XMP_ERROR_SYSTEM;
		goto err;
	}
		
	/* Init instrument */

	xxi->sub = calloc(sizeof(struct xmp_subinstrument), 1);
	if (xxi->sub == NULL) {
		retval = -XMP_ERROR_SYSTEM;
		goto err1;
	}

	xxi->vol = m->volbase;
	xxi->nsm = 1;
	xxi->sub[0].sid = num;
	xxi->sub[0].vol = xxi->vol;
	xxi->sub[0].pan = 0x80;

	/* Load sample */

	magic = hio_read32b(h);
	if (magic != 0x52494646) {	/* RIFF */
		retval = -XMP_ERROR_FORMAT;
		goto err2;
	}

	hio_seek(h, 22, SEEK_SET);
	chn = hio_read16l(h);
	if (chn != 1) {
		retval = -XMP_ERROR_FORMAT;
		goto err2;
	}

	rate = hio_read32l(h);

	hio_seek(h, 34, SEEK_SET);
	bits = hio_read16l(h);

	hio_seek(h, 40, SEEK_SET);
	size = hio_read32l(h) / (bits / 8);

	c2spd_to_note(rate, &xxi->sub[0].xpo, &xxi->sub[0].fin);

	xxs->len = 8 * size / bits;
	xxs->lps = 0;
	xxs->lpe = 0;
	xxs->flg = bits == 16 ? XMP_SAMPLE_16BIT : 0;

	xxs->data = malloc(size);
	if (xxs->data == NULL) {
		retval = -XMP_ERROR_SYSTEM;
		goto err2;
	}

	hio_seek(h, 44, SEEK_SET);
	hio_read(xxs->data, 1, size, h);
	hio_close(h);

	return 0;
	
    err2:
	free(xxi->sub);
	xxi->sub = NULL;
    err1:
	hio_close(h);
    err:
	return retval;
}
示例#15
0
static int load_patterns(struct module_data *m, int version, HIO_HANDLE *f)
{
    struct xmp_module *mod = &m->mod;
    struct xm_pattern_header xph;
    struct xmp_event *event;
    uint8 *patbuf, *pat, b;
    int i, j, r;

    mod->pat++;
    if (pattern_init(mod) < 0)
	return -1;

    D_(D_INFO "Stored patterns: %d", mod->pat - 1);

    /* Endianism fixed by Miodrag Vallat <*****@*****.**>
     * Mon, 04 Jan 1999 11:17:20 +0100
     */
    for (i = 0; i < mod->pat - 1; i++) {
    	const int headsize = version > 0x0102 ? 9 : 8;

	xph.length = hio_read32l(f);
	xph.packing = hio_read8(f);
	xph.rows = version > 0x0102 ? hio_read16l(f) : hio_read8(f) + 1;

	/* Sanity check */
	if (xph.rows > 256)
	    goto err;

	xph.datasize = hio_read16l(f);
	hio_seek(f, xph.length - headsize, SEEK_CUR);
	if (hio_error(f)) {
            goto err;
	}

	r = xph.rows;
	if (r == 0)
	    r = 0x100;

	if (pattern_tracks_alloc(mod, i, r) < 0)
	    goto err;

	if (xph.datasize) {
	    int size = xph.datasize;

	    pat = patbuf = calloc(1, size);
	    if (patbuf == NULL)
		goto err;

	    hio_read(patbuf, 1, size, f);
	    for (j = 0; j < (mod->chn * r); j++) {

		/*if ((pat - patbuf) >= xph.datasize)
		    break;*/

		event = &EVENT(i, j % mod->chn, j / mod->chn);

		if (--size < 0)
		    goto err2;

		if ((b = *pat++) & XM_EVENT_PACKING) {
		    if (b & XM_EVENT_NOTE_FOLLOWS) {
			if (--size < 0)
			    goto err2;
			event->note = *pat++;
		    }
		    if (b & XM_EVENT_INSTRUMENT_FOLLOWS) {
			if (--size < 0)
			    goto err2;
			event->ins = *pat++;
		    }
		    if (b & XM_EVENT_VOLUME_FOLLOWS) {
			if (--size < 0)
			    goto err2;
			event->vol = *pat++;
		    }
		    if (b & XM_EVENT_FXTYPE_FOLLOWS) {
			if (--size < 0)
			    goto err2;
			event->fxt = *pat++;
		    }
		    if (b & XM_EVENT_FXPARM_FOLLOWS) {
			if (--size < 0)
			    goto err2;
			event->fxp = *pat++;
		    }
		} else {
                    size -=4;
		    if (size < 0)
			goto err2;
		    event->note = b;
		    event->ins = *pat++;
		    event->vol = *pat++;
		    event->fxt = *pat++;
		    event->fxp = *pat++;
		}

		/* Sanity check */
		switch (event->fxt) {
		case 18: case 19:
		case 22: case 23: case 24:
		case 26:
		case 28:
		case 30: case 31: case 32:
			event->fxt = 0;
		}
		if (event->fxt > 34) {
			event->fxt = 0;
		}

		if (event->note == 0x61) {
		    /* See OpenMPT keyoff+instr.xm test case */
		    if (event->fxt == 0x0e && MSN(event->fxp) == 0x0d) {
			event->note = XMP_KEY_OFF;
		    } else {
		    	event->note = event->ins ? XMP_KEY_FADE : XMP_KEY_OFF;
		    }
		} else if (event->note > 0) {
		    event->note += 12;
		}

		if (event->fxt == 0x0e) {
			switch (event->fxp) {
			case 0x43:
			case 0x73:
				event->fxp--;
				break;
			}
		}

		if (!event->vol)
		    continue;

		/* Volume set */
		if ((event->vol >= 0x10) && (event->vol <= 0x50)) {
		    event->vol -= 0x0f;
		    continue;
		}
		/* Volume column effects */
		switch (event->vol >> 4) {
		case 0x06:	/* Volume slide down */
		    event->f2t = FX_VOLSLIDE_2;
		    event->f2p = event->vol - 0x60;
		    break;
		case 0x07:	/* Volume slide up */
		    event->f2t = FX_VOLSLIDE_2;
		    event->f2p = (event->vol - 0x70) << 4;
		    break;
		case 0x08:	/* Fine volume slide down */
		    event->f2t = FX_EXTENDED;
		    event->f2p = (EX_F_VSLIDE_DN << 4) | (event->vol - 0x80);
		    break;
		case 0x09:	/* Fine volume slide up */
		    event->f2t = FX_EXTENDED;
		    event->f2p = (EX_F_VSLIDE_UP << 4) | (event->vol - 0x90);
		    break;
		case 0x0a:	/* Set vibrato speed */
		    event->f2t = FX_VIBRATO;
		    event->f2p = (event->vol - 0xa0) << 4;
		    break;
		case 0x0b:	/* Vibrato */
		    event->f2t = FX_VIBRATO;
		    event->f2p = event->vol - 0xb0;
		    break;
		case 0x0c:	/* Set panning */
		    event->f2t = FX_SETPAN;
		    event->f2p = (event->vol - 0xc0) << 4;
		    break;
		case 0x0d:	/* Pan slide left */
		    event->f2t = FX_PANSL_NOMEM;
		    event->f2p = (event->vol - 0xd0) << 4;
		    break;
		case 0x0e:	/* Pan slide right */
		    event->f2t = FX_PANSL_NOMEM;
		    event->f2p = event->vol - 0xe0;
		    break;
		case 0x0f:	/* Tone portamento */
		    event->f2t = FX_TONEPORTA;
		    event->f2p = (event->vol - 0xf0) << 4;

		    /* From OpenMPT TonePortamentoMemory.xm:
		     * "Another nice bug (...) is the combination of both
		     *  portamento commands (Mx and 3xx) in the same cell:
		     *  The 3xx parameter is ignored completely, and the Mx
		     *  parameter is doubled. (M2 3FF is the same as M4 000)
		     */
		    if (event->fxt == FX_TONEPORTA || event->fxt == FX_TONE_VSLIDE) {
			if (event->fxt == FX_TONEPORTA) {
			    event->fxt = 0;
			} else {
			    event->fxt = FX_VOLSLIDE;
			}
			event->fxp = 0;

			if (event->f2p < 0x80) {
				event->f2p <<= 1;
			} else {
				event->f2p = 0xff;
			}
		    }

		    /* From OpenMPT porta-offset.xm:
		     * "If there is a portamento command next to an offset
		     *  command, the offset command is ignored completely. In
		     *  particular, the offset parameter is not memorized."
		     */
		    if (event->fxt == FX_OFFSET && event->f2t == FX_TONEPORTA) {
			event->fxt = event->fxp = 0;
		    }
		    break;
		}
		event->vol = 0;
	    }
	    free(patbuf);
	}
    }
示例#16
0
static int psm_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	int c, r, i;
	struct xmp_event *event;
	uint8 buf[1024];
	uint32 p_ord, p_chn, p_pat, p_ins;
	uint32 p_smp[64];
	int type, ver /*, mode*/;
 
	LOAD_INIT();

	hio_read32b(f);

	hio_read(buf, 1, 60, f);
	strncpy(mod->name, (char *)buf, 60);

	type = hio_read8(f);		/* song type */
	ver = hio_read8(f);		/* song version */
	/*mode =*/ hio_read8(f);	/* pattern version */

	if (type & 0x01)		/* song mode not supported */
		return -1;

	libxmp_set_type(m, "Protracker Studio PSM %d.%02d", MSN(ver), LSN(ver));

	mod->spd = hio_read8(f);
	mod->bpm = hio_read8(f);
	hio_read8(f);			/* master volume */
	hio_read16l(f);			/* song length */
	mod->len = hio_read16l(f);
	mod->pat = hio_read16l(f);
	mod->ins = hio_read16l(f);
	hio_read16l(f);			/* ignore channels to play */
	mod->chn = hio_read16l(f);	/* use channels to proceed */
	mod->smp = mod->ins;
	mod->trk = mod->pat * mod->chn;

	/* Sanity check */
	if (mod->len > 256 || mod->pat > 256 || mod->ins > 255 ||
	    mod->chn > XMP_MAX_CHANNELS) {
		return -1;
        }

	p_ord = hio_read32l(f);
	p_chn = hio_read32l(f);
	p_pat = hio_read32l(f);
	p_ins = hio_read32l(f);

	/* should be this way but fails with Silverball song 6 */
	//mod->flg |= ~type & 0x02 ? XXM_FLG_MODRNG : 0;

	m->c4rate = C4_NTSC_RATE;

	MODULE_INFO();

	hio_seek(f, start + p_ord, SEEK_SET);
	hio_read(mod->xxo, 1, mod->len, f);

	hio_seek(f, start + p_chn, SEEK_SET);
	hio_read(buf, 1, 16, f);

	if (libxmp_init_instrument(m) < 0)
		return -1;

	hio_seek(f, start + p_ins, SEEK_SET);
	for (i = 0; i < mod->ins; i++) {
		uint16 flags, c2spd;
		int finetune;

		if (libxmp_alloc_subinstrument(mod, i, 1) < 0)
			return -1;

		hio_read(buf, 1, 13, f);	/* sample filename */
		hio_read(buf, 1, 24, f);	/* sample description */
		buf[24] = 0;			/* add string termination */
		strncpy((char *)mod->xxi[i].name, (char *)buf, 24);
		p_smp[i] = hio_read32l(f);
		hio_read32l(f);			/* memory location */
		hio_read16l(f);			/* sample number */
		flags = hio_read8(f);		/* sample type */
		mod->xxs[i].len = hio_read32l(f); 
		mod->xxs[i].lps = hio_read32l(f);
		mod->xxs[i].lpe = hio_read32l(f);
		finetune = (int8)(hio_read8(f) << 4);
		mod->xxi[i].sub[0].vol = hio_read8(f);
		c2spd = hio_read16l(f);
		mod->xxi[i].sub[0].pan = 0x80;
		mod->xxi[i].sub[0].sid = i;
		mod->xxs[i].flg = flags & 0x80 ? XMP_SAMPLE_LOOP : 0;
		mod->xxs[i].flg |= flags & 0x20 ? XMP_SAMPLE_LOOP_BIDIR : 0;

		libxmp_c2spd_to_note(c2spd, &mod->xxi[i].sub[0].xpo,
						&mod->xxi[i].sub[0].fin);
		mod->xxi[i].sub[0].fin += finetune;

		if (mod->xxs[i].len > 0)
			mod->xxi[i].nsm = 1;

		D_(D_INFO "[%2X] %-22.22s %04x %04x %04x %c V%02x %5d",
			i, mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps,
			mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ?
			'L' : ' ', mod->xxi[i].sub[0].vol, c2spd);
	}
	
	if (libxmp_init_pattern(mod) < 0)
		return -1;

	D_(D_INFO "Stored patterns: %d", mod->pat);

	hio_seek(f, start + p_pat, SEEK_SET);
	for (i = 0; i < mod->pat; i++) {
		int len;
		uint8 b, rows, chan;

		len = hio_read16l(f) - 4;
		rows = hio_read8(f);
		if (rows > 64) {
			return -1;
		}
		chan = hio_read8(f);
		if (chan > 32) {
			return -1;
		}

		if (libxmp_alloc_pattern_tracks(mod, i, rows) < 0)
			return -1;

		for (r = 0; r < rows; r++) {
			while (len > 0) {
				b = hio_read8(f);
				len--;

				if (b == 0)
					break;
	
				c = b & 0x0f;
				if (c >= mod->chn)
					return -1;
				event = &EVENT(i, c, r);
	
				if (b & 0x80) {
					event->note = hio_read8(f) + 36 + 1;
					event->ins = hio_read8(f);
					len -= 2;
				}
	
				if (b & 0x40) {
					event->vol = hio_read8(f) + 1;
					len--;
				}
	
				if (b & 0x20) {
					event->fxt = hio_read8(f);
					event->fxp = hio_read8(f);
					len -= 2;
				}
			}
		}

		if (len > 0)
			hio_seek(f, len, SEEK_CUR);
	}

	/* Read samples */

	D_(D_INFO "Stored samples: %d", mod->smp);

	for (i = 0; i < mod->ins; i++) {
		hio_seek(f, start + p_smp[i], SEEK_SET);
		if (libxmp_load_sample(m, f, SAMPLE_FLAG_DIFF,
				&mod->xxs[mod->xxi[i].sub[0].sid], NULL) < 0)
			return -1;
	}

	return 0;
}
示例#17
0
static int rtm_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
	struct xmp_module *mod = &m->mod;
	int i, j, r;
	struct xmp_event *event;
	struct ObjectHeader oh;
	struct RTMMHeader rh;
	struct RTNDHeader rp;
	struct RTINHeader ri;
	struct RTSMHeader rs;
	int offset, smpnum, version;
	char tracker_name[21], composer[33];

	LOAD_INIT();

	if (read_object_header(f, &oh, "RTMM") < 0)
		return -1;

	version = oh.version;

	hio_read(tracker_name, 1, 20, f);
	tracker_name[20] = 0;
	hio_read(composer, 1, 32, f);
	composer[32] = 0;
	rh.flags = hio_read16l(f);	/* bit 0: linear table, bit 1: track names */
	rh.ntrack = hio_read8(f);
	rh.ninstr = hio_read8(f);
	rh.nposition = hio_read16l(f);
	rh.npattern = hio_read16l(f);
	rh.speed = hio_read8(f);
	rh.tempo = hio_read8(f);
	hio_read(&rh.panning, 32, 1, f);
	rh.extraDataSize = hio_read32l(f);

	/* Sanity check */
	if (rh.nposition > 255 || rh.ntrack > 32 || rh.npattern > 255) {
		return -1;
	}

	if (version >= 0x0112)
		hio_seek(f, 32, SEEK_CUR);		/* skip original name */

	for (i = 0; i < rh.nposition; i++) {
		mod->xxo[i] = hio_read16l(f);
		if (mod->xxo[i] >= rh.npattern) {
			return -1;
		}
	}
	
	strncpy(mod->name, oh.name, 20);
	snprintf(mod->type, XMP_NAME_SIZE, "%s RTM %x.%02x",
				tracker_name, version >> 8, version & 0xff);
	/* strncpy(m->author, composer, XMP_NAME_SIZE); */

	mod->len = rh.nposition;
	mod->pat = rh.npattern;
	mod->chn = rh.ntrack;
	mod->trk = mod->chn * mod->pat;
	mod->ins = rh.ninstr;
	mod->spd = rh.speed;
	mod->bpm = rh.tempo;

	m->c4rate = C4_NTSC_RATE;
	m->period_type = rh.flags & 0x01 ? PERIOD_LINEAR : PERIOD_AMIGA;

	MODULE_INFO();

	for (i = 0; i < mod->chn; i++)
		mod->xxc[i].pan = rh.panning[i] & 0xff;

	if (libxmp_init_pattern(mod) < 0)
		return -1;

	D_(D_INFO "Stored patterns: %d", mod->pat);

	offset = 42 + oh.headerSize + rh.extraDataSize;

	for (i = 0; i < mod->pat; i++) {
		uint8 c;

		hio_seek(f, start + offset, SEEK_SET);

		if (read_object_header(f, &oh, "RTND") < 0) {
			D_(D_CRIT "Error reading pattern %d", i);
			return -1;
		}
	
		rp.flags = hio_read16l(f);
		rp.ntrack = hio_read8(f);
		rp.nrows = hio_read16l(f);
		rp.datasize = hio_read32l(f);

		/* Sanity check */
		if (rp.ntrack > rh.ntrack || rp.nrows > 256) {
			return -1;
		}

		offset += 42 + oh.headerSize + rp.datasize;

		if (libxmp_alloc_pattern_tracks(mod, i, rp.nrows) < 0)
			return -1;

		for (r = 0; r < rp.nrows; r++) {
			for (j = 0; /*j < rp.ntrack */; j++) {

				c = hio_read8(f);
				if (c == 0)		/* next row */
					break;

				/* Sanity check */
				if (j >= rp.ntrack) {
					return -1;
				}

				event = &EVENT(i, j, r);

				if (c & 0x01) {		/* set track */
					j = hio_read8(f);

					/* Sanity check */
					if (j >= rp.ntrack) {
						return -1;
					}

					event = &EVENT(i, j, r);
				}
				if (c & 0x02) {		/* read note */
					event->note = hio_read8(f) + 1;
					if (event->note == 0xff) {
						event->note = XMP_KEY_OFF;
					} else {
						event->note += 12;
					}
				}
				if (c & 0x04)		/* read instrument */
					event->ins = hio_read8(f);
				if (c & 0x08)		/* read effect */
					event->fxt = hio_read8(f);
				if (c & 0x10)		/* read parameter */
					event->fxp = hio_read8(f);
				if (c & 0x20)		/* read effect 2 */
					event->f2t = hio_read8(f);
				if (c & 0x40)		/* read parameter 2 */
					event->f2p = hio_read8(f);
			}
		}
	}

	/*
	 * load instruments
	 */

	D_(D_INFO "Instruments: %d", mod->ins);

	hio_seek(f, start + offset, SEEK_SET);

	/* ESTIMATED value! We don't know the actual value at this point */
	mod->smp = MAX_SAMP;

	if (libxmp_init_instrument(m) < 0)
		return -1;

	smpnum = 0;
	for (i = 0; i < mod->ins; i++) {
		struct xmp_instrument *xxi = &mod->xxi[i];

		if (read_object_header(f, &oh, "RTIN") < 0) {
			D_(D_CRIT "Error reading instrument %d", i);
			return -1;
		}

		libxmp_instrument_name(mod, i, (uint8 *)&oh.name, 32);

		if (oh.headerSize == 0) {
			D_(D_INFO "[%2X] %-26.26s %2d ", i,
						xxi->name, xxi->nsm);
			ri.nsample = 0;
			continue;
		}

		ri.nsample = hio_read8(f);
		ri.flags = hio_read16l(f);	/* bit 0 : default panning enabled */
		if (hio_read(&ri.table, 1, 120, f) != 120)
			return -1;

		ri.volumeEnv.npoint = hio_read8(f);

		/* Sanity check */
		if (ri.volumeEnv.npoint >= 12)
			return -1;

		for (j = 0; j < 12; j++) {
			ri.volumeEnv.point[j].x = hio_read32l(f);
			ri.volumeEnv.point[j].y = hio_read32l(f);
		}
		ri.volumeEnv.sustain = hio_read8(f);
		ri.volumeEnv.loopstart = hio_read8(f);
		ri.volumeEnv.loopend = hio_read8(f);
		ri.volumeEnv.flags = hio_read16l(f); /* bit 0:enable 1:sus 2:loop */
		
		ri.panningEnv.npoint = hio_read8(f);

		/* Sanity check */
		if (ri.panningEnv.npoint >= 12)
			return -1;

		for (j = 0; j < 12; j++) {
			ri.panningEnv.point[j].x = hio_read32l(f);
			ri.panningEnv.point[j].y = hio_read32l(f);
		}
		ri.panningEnv.sustain = hio_read8(f);
		ri.panningEnv.loopstart = hio_read8(f);
		ri.panningEnv.loopend = hio_read8(f);
		ri.panningEnv.flags = hio_read16l(f);

		ri.vibflg = hio_read8(f);
		ri.vibsweep = hio_read8(f);
		ri.vibdepth = hio_read8(f);
		ri.vibrate = hio_read8(f);
		ri.volfade = hio_read16l(f);

		if (version >= 0x0110) {
			ri.midiPort = hio_read8(f);
			ri.midiChannel = hio_read8(f);
			ri.midiProgram = hio_read8(f);
			ri.midiEnable = hio_read8(f);
		}
		if (version >= 0x0112) {
			ri.midiTranspose = hio_read8(f);
			ri.midiBenderRange = hio_read8(f);
			ri.midiBaseVolume = hio_read8(f);
			ri.midiUseVelocity = hio_read8(f);
		}

		xxi->nsm = ri.nsample;

		D_(D_INFO "[%2X] %-26.26s %2d", i, xxi->name, xxi->nsm);

		if (xxi->nsm > 16)
			xxi->nsm = 16;

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

		for (j = 0; j < 120; j++)
			xxi->map[j].ins = ri.table[j];

		/* Envelope */
		xxi->rls = ri.volfade;
		xxi->aei.npt = ri.volumeEnv.npoint;
		xxi->aei.sus = ri.volumeEnv.sustain;
		xxi->aei.lps = ri.volumeEnv.loopstart;
		xxi->aei.lpe = ri.volumeEnv.loopend;
		xxi->aei.flg = ri.volumeEnv.flags;
		xxi->pei.npt = ri.panningEnv.npoint;
		xxi->pei.sus = ri.panningEnv.sustain;
		xxi->pei.lps = ri.panningEnv.loopstart;
		xxi->pei.lpe = ri.panningEnv.loopend;
		xxi->pei.flg = ri.panningEnv.flags;

		for (j = 0; j < xxi->aei.npt; j++) {
			xxi->aei.data[j * 2 + 0] = ri.volumeEnv.point[j].x;
			xxi->aei.data[j * 2 + 1] = ri.volumeEnv.point[j].y / 2;
		}
		for (j = 0; j < xxi->pei.npt; j++) {
			xxi->pei.data[j * 2 + 0] = ri.panningEnv.point[j].x;
			xxi->pei.data[j * 2 + 1] = 32 + ri.panningEnv.point[j].y / 2;
		}

		/* For each sample */
		for (j = 0; j < xxi->nsm; j++, smpnum++) {
			struct xmp_subinstrument *sub = &xxi->sub[j];
			struct xmp_sample *xxs;

			if (read_object_header(f, &oh, "RTSM") < 0) {
				D_(D_CRIT "Error reading sample %d", j);
				return -1;
			}

			rs.flags = hio_read16l(f);
			rs.basevolume = hio_read8(f);
			rs.defaultvolume = hio_read8(f);
			rs.length = hio_read32l(f);
			rs.loop = hio_read32l(f);
			rs.loopbegin = hio_read32l(f);
			rs.loopend = hio_read32l(f);
			rs.basefreq = hio_read32l(f);
			rs.basenote = hio_read8(f);
			rs.panning = hio_read8(f);

			libxmp_c2spd_to_note(rs.basefreq, &sub->xpo, &sub->fin);
			sub->xpo += 48 - rs.basenote;
			sub->vol = rs.defaultvolume * rs.basevolume / 0x40;
			sub->pan = 0x80 + rs.panning * 2;
			sub->vwf = ri.vibflg;
			sub->vde = ri.vibdepth << 2;
			sub->vra = ri.vibrate;
			sub->vsw = ri.vibsweep;
			sub->sid = smpnum;

			if (smpnum >= mod->smp) {
				 mod->xxs = libxmp_realloc_samples(mod->xxs,
						&mod->smp, mod->smp * 3 / 2);
				if (mod->xxs == NULL)
					return -1;
			}
 			xxs = &mod->xxs[smpnum];

			libxmp_copy_adjust(xxs->name, (uint8 *)oh.name, 31);

			xxs->len = rs.length;
			xxs->lps = rs.loopbegin;
			xxs->lpe = rs.loopend;

			xxs->flg = 0;
			if (rs.flags & 0x02) {
				xxs->flg |= XMP_SAMPLE_16BIT;
				xxs->len >>= 1;
				xxs->lps >>= 1;
				xxs->lpe >>= 1;
			}

			xxs->flg |= rs.loop & 0x03 ?  XMP_SAMPLE_LOOP : 0;
			xxs->flg |= rs.loop == 2 ? XMP_SAMPLE_LOOP_BIDIR : 0;

			D_(D_INFO "  [%1x] %05x%c%05x %05x %c "
						"V%02x F%+04d P%02x R%+03d",
				j, xxs->len,
				xxs->flg & XMP_SAMPLE_16BIT ? '+' : ' ',
				xxs->lps, xxs->lpe,
				xxs->flg & XMP_SAMPLE_LOOP_BIDIR ? 'B' :
				xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
				sub->vol, sub->fin, sub->pan, sub->xpo);

			if (libxmp_load_sample(m, f, SAMPLE_FLAG_DIFF, xxs, NULL) < 0)
				return -1;
		}
	}
示例#18
0
文件: stm_load.c 项目: GCrean/libxmp
static int stm_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
    struct xmp_module *mod = &m->mod;
    int i, j;
    struct xmp_event *event;
    struct stm_file_header sfh;
    uint8 b;
    int bmod2stm = 0;

    LOAD_INIT();

    hio_read(&sfh.name, 20, 1, f);		/* ASCIIZ song name */
    hio_read(&sfh.magic, 8, 1, f);		/* '!Scream!' */
    sfh.rsvd1 = hio_read8(f);			/* '\x1a' */
    sfh.type = hio_read8(f);			/* 1=song, 2=module */
    sfh.vermaj = hio_read8(f);			/* Major version number */
    sfh.vermin = hio_read8(f);			/* Minor version number */
    sfh.tempo = hio_read8(f);			/* Playback tempo */
    sfh.patterns = hio_read8(f);		/* Number of patterns */
    sfh.gvol = hio_read8(f);			/* Global volume */
    hio_read(&sfh.rsvd2, 13, 1, f);		/* Reserved */

    for (i = 0; i < 31; i++) {
	hio_read(&sfh.ins[i].name, 12, 1, f);	/* ASCIIZ instrument name */
	sfh.ins[i].id = hio_read8(f);		/* Id=0 */
	sfh.ins[i].idisk = hio_read8(f);	/* Instrument disk */
	sfh.ins[i].rsvd1 = hio_read16l(f);	/* Reserved */
	sfh.ins[i].length = hio_read16l(f);	/* Sample length */
	sfh.ins[i].loopbeg = hio_read16l(f);	/* Loop begin */
	sfh.ins[i].loopend = hio_read16l(f);	/* Loop end */
	sfh.ins[i].volume = hio_read8(f);	/* Playback volume */
	sfh.ins[i].rsvd2 = hio_read8(f);	/* Reserved */
	sfh.ins[i].c2spd = hio_read16l(f);	/* C4 speed */
	sfh.ins[i].rsvd3 = hio_read32l(f);	/* Reserved */
	sfh.ins[i].paralen = hio_read16l(f);	/* Length in paragraphs */
    }

    if (!strncmp ((char *)sfh.magic, "BMOD2STM", 8))
	bmod2stm = 1;

    mod->pat = sfh.patterns;
    mod->trk = mod->pat * mod->chn;
    mod->spd = MSN (sfh.tempo);
    mod->ins = 31;
    mod->smp = mod->ins;
    m->c4rate = C4_NTSC_RATE;

    copy_adjust(mod->name, sfh.name, 20);

    if (bmod2stm) {
	snprintf(mod->type, XMP_NAME_SIZE, "BMOD2STM STM");
    } else {
	snprintf(mod->type, XMP_NAME_SIZE, "Scream Tracker %d.%02d STM",
						sfh.vermaj, sfh.vermin);
    }

    MODULE_INFO();

    if (instrument_init(mod) < 0)
	return -1;

    /* Read and convert instruments and samples */
    for (i = 0; i < mod->ins; i++) {
	if (subinstrument_alloc(mod, i, 1) < 0)
	    return -1;

	mod->xxs[i].len = sfh.ins[i].length;
	mod->xxs[i].lps = sfh.ins[i].loopbeg;
	mod->xxs[i].lpe = sfh.ins[i].loopend;
	if (mod->xxs[i].lpe == 0xffff)
	    mod->xxs[i].lpe = 0;
	mod->xxs[i].flg = mod->xxs[i].lpe > 0 ? XMP_SAMPLE_LOOP : 0;
	mod->xxi[i].sub[0].vol = sfh.ins[i].volume;
	mod->xxi[i].sub[0].pan = 0x80;
	mod->xxi[i].sub[0].sid = i;

	if (mod->xxs[i].len > 0)
		mod->xxi[i].nsm = 1;

	instrument_name(mod, i, sfh.ins[i].name, 12);

	D_(D_INFO "[%2X] %-14.14s %04x %04x %04x %c V%02x %5d", i,
		mod->xxi[i].name, mod->xxs[i].len, mod->xxs[i].lps,
		mod->xxs[i].lpe, mod->xxs[i].flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
		mod->xxi[i].sub[0].vol, sfh.ins[i].c2spd);

	sfh.ins[i].c2spd = 8363 * sfh.ins[i].c2spd / 8448;
	c2spd_to_note (sfh.ins[i].c2spd, &mod->xxi[i].sub[0].xpo, &mod->xxi[i].sub[0].fin);
    }

    hio_read(mod->xxo, 1, 128, f);

    for (i = 0; i < 128; i++)
	if (mod->xxo[i] >= mod->pat)
	    break;

    mod->len = i;

    D_(D_INFO "Module length: %d", mod->len);

    if (pattern_init(mod) < 0)
	return -1;

    /* Read and convert patterns */
    D_(D_INFO "Stored patterns: %d", mod->pat);

    for (i = 0; i < mod->pat; i++) {
	if (pattern_tracks_alloc(mod, i, 64) < 0)
	    return -1;

	for (j = 0; j < 64 * mod->chn; j++) {
	    event = &EVENT (i, j % mod->chn, j / mod->chn);
	    b = hio_read8(f);
	    memset (event, 0, sizeof (struct xmp_event));
	    switch (b) {
	    case 251:
	    case 252:
	    case 253:
		break;
	    case 255:
		b = 0;
	    default:
		event->note = b ? 13 + LSN(b) + 12 * (2 + MSN(b)) : 0;
		b = hio_read8(f);
		event->vol = b & 0x07;
		event->ins = (b & 0xf8) >> 3;
		b = hio_read8(f);
		event->vol += (b & 0xf0) >> 1;
		if (event->vol > 0x40)
		    event->vol = 0;
		else
		    event->vol++;
		event->fxt = fx[LSN(b)];
		event->fxp = hio_read8(f);
		switch (event->fxt) {
		case FX_SPEED:
		    event->fxp = MSN (event->fxp);
		    break;
		case FX_NONE:
		    event->fxp = event->fxt = 0;
		    break;
		}
	    }
	}
    }

    /* Read samples */
    D_(D_INFO "Stored samples: %d", mod->smp);

    for (i = 0; i < mod->ins; i++) {
	if (mod->xxs[i].len > 1) {
	    if (load_sample(m, f, 0, &mod->xxs[i], NULL) < 0)
		return -1;
	} else {
	    mod->xxi[i].nsm = 0;
	}
    }

    m->quirk |= QUIRK_VSALL | QUIRKS_ST3;
    m->read_event_type = READ_EVENT_ST3;

    return 0;
}
示例#19
0
static int coco_test(HIO_HANDLE *f, char *t, const int start)
{
	uint8 x, buf[20];
	uint32 y;
	int n, i;

	x = hio_read8(f);

	/* check number of channels */
	if (x != 0x84 && x != 0x88)
		return -1;

	hio_read(buf, 1, 20, f);		/* read title */
	if (check_cr(buf, 20) != 0)
		return -1;

	n = hio_read8(f);			/* instruments */
	if (n > 100)
		return -1;

	hio_read8(f);			/* sequences */
	hio_read8(f);			/* patterns */

	y = hio_read32l(f);
	if (y < 64 || y > 0x00100000)	/* offset of sequence table */
		return -1;

	y = hio_read32l(f);			/* offset of patterns */
	if (y < 64 || y > 0x00100000)
		return -1;

	for (i = 0; i < n; i++) {
		int ofs = hio_read32l(f);
		int len = hio_read32l(f);
		int vol = hio_read32l(f);
		int lps = hio_read32l(f);
		int lsz = hio_read32l(f);

		if (ofs < 64 || ofs > 0x00100000)
			return -1;

		if (vol > 0xff)
			return -1;

		if (len > 0x00100000 || lps > 0x00100000 || lsz > 0x00100000)
			return -1;

		if (lps + lsz - 1 > len)
			return -1;

		hio_read(buf, 1, 11, f);
		if (check_cr(buf, 11) != 0)
			return -1;

		hio_read8(f);	/* unused */
	}

	hio_seek(f, start + 1, SEEK_SET);
	libxmp_read_title(f, t, 20);

#if 0
	for (i = 0; i < 20; i++) {
		if (t[i] == 0x0d)
			t[i] = 0;
	}
#endif
	
	return 0;
}
示例#20
0
static int ptm_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
    struct xmp_module *mod = &m->mod;
    int c, r, i, smp_ofs[256];
    struct xmp_event *event;
    struct ptm_file_header pfh;
    struct ptm_instrument_header pih;
    uint8 n, b;

    LOAD_INIT();

    /* Load and convert header */

    hio_read(&pfh.name, 28, 1, f);	/* Song name */
    pfh.doseof = hio_read8(f);		/* 0x1a */
    pfh.vermin = hio_read8(f);		/* Minor version */
    pfh.vermaj = hio_read8(f);		/* Major type */
    pfh.rsvd1 = hio_read8(f);		/* Reserved */
    pfh.ordnum = hio_read16l(f);	/* Number of orders (must be even) */
    pfh.insnum = hio_read16l(f);	/* Number of instruments */
    pfh.patnum = hio_read16l(f);	/* Number of patterns */
    pfh.chnnum = hio_read16l(f);	/* Number of channels */
    pfh.flags = hio_read16l(f);		/* Flags (set to 0) */
    pfh.rsvd2 = hio_read16l(f);		/* Reserved */
    pfh.magic = hio_read32b(f); 	/* 'PTMF' */

    if (pfh.magic != MAGIC_PTMF)
	return -1;

    /* Sanity check */
    if (pfh.ordnum > 256 || pfh.insnum > 255 || pfh.patnum > 128 ||
      pfh.chnnum > 32) {
	return -1;
    }

    hio_read(&pfh.rsvd3, 16, 1, f);	/* Reserved */
    hio_read(&pfh.chset, 32, 1, f);	/* Channel settings */
    hio_read(&pfh.order, 256, 1, f);	/* Orders */
    for (i = 0; i < 128; i++)
	pfh.patseg[i] = hio_read16l(f);

    mod->len = pfh.ordnum;
    mod->ins = pfh.insnum;
    mod->pat = pfh.patnum;
    mod->chn = pfh.chnnum;
    mod->trk = mod->pat * mod->chn;
    mod->smp = mod->ins;
    mod->spd = 6;
    mod->bpm = 125;
    memcpy (mod->xxo, pfh.order, 256);

    m->c4rate = C4_NTSC_RATE;

    copy_adjust(mod->name, pfh.name, 28);
    set_type(m, "Poly Tracker PTM %d.%02x",
	pfh.vermaj, pfh.vermin);

    MODULE_INFO();

    if (instrument_init(mod) < 0)
	return -1;

    /* Read and convert instruments and samples */

    for (i = 0; i < mod->ins; i++) {
	struct xmp_instrument *xxi = &mod->xxi[i];
	struct xmp_sample *xxs = &mod->xxs[i];
	struct xmp_subinstrument *sub;

	pih.type = hio_read8(f);		/* Sample type */
	hio_read(&pih.dosname, 12, 1, f);	/* DOS file name */
	pih.vol = hio_read8(f);			/* Volume */
	pih.c4spd = hio_read16l(f);		/* C4 speed */
	pih.smpseg = hio_read16l(f);		/* Sample segment (not used) */
	pih.smpofs = hio_read32l(f);		/* Sample offset */
	pih.length = hio_read32l(f);		/* Length */
	pih.loopbeg = hio_read32l(f);		/* Loop begin */
	pih.loopend = hio_read32l(f);		/* Loop end */
	pih.gusbeg = hio_read32l(f);		/* GUS begin address */
	pih.guslps = hio_read32l(f);		/* GUS loop start address */
	pih.guslpe = hio_read32l(f);		/* GUS loop end address */
	pih.gusflg = hio_read8(f);		/* GUS loop flags */
	pih.rsvd1 = hio_read8(f);		/* Reserved */
	hio_read(&pih.name, 28, 1, f);		/* Instrument name */
	pih.magic = hio_read32b(f);		/* 'PTMS' */

	if ((pih.type & 3) != 1)
	    continue;

	if (subinstrument_alloc(mod, i, 1) < 0)
	    return -1;

	sub = &xxi->sub[0];

	smp_ofs[i] = pih.smpofs;
	xxs->len = pih.length;
	xxs->lps = pih.loopbeg;
	xxs->lpe = pih.loopend;

	if (mod->xxs[i].len > 0)
		mod->xxi[i].nsm = 1;

	xxs->flg = 0;
	if (pih.type & 0x04) {
	    xxs->flg |= XMP_SAMPLE_LOOP;
	}
	if (pih.type & 0x08) {
	    xxs->flg |= XMP_SAMPLE_LOOP | XMP_SAMPLE_LOOP_BIDIR;
	}
	if (pih.type & 0x10) {
	    xxs->flg |= XMP_SAMPLE_16BIT;
	    xxs->len >>= 1;
	    xxs->lps >>= 1;
	    xxs->lpe >>= 1;
	}

	sub->vol = pih.vol;
	sub->pan = 0x80;
	sub->sid = i;
	pih.magic = 0;

	instrument_name(mod, i, pih.name, 28);

	D_(D_INFO "[%2X] %-28.28s %05x%c%05x %05x %c V%02x %5d",
		i, mod->xxi[i].name, mod->xxs[i].len,
		pih.type & 0x10 ? '+' : ' ',
		xxs->lps, xxs->lpe, xxs->flg & XMP_SAMPLE_LOOP ? 'L' : ' ',
		sub->vol, pih.c4spd);

	/* Convert C4SPD to relnote/finetune */
	c2spd_to_note(pih.c4spd, &sub->xpo, &sub->fin);
    }