예제 #1
0
파일: hio.c 프로젝트: kacmem/zxtune
uint16 hio_read16l(HIO_HANDLE *h)
{
	if (HIO_HANDLE_TYPE(h) == HIO_HANDLE_TYPE_FILE) {
		return read16l(h->f);
	} else {
		ptrdiff_t can_read = CAN_READ(h);
		if (can_read >= 2) {
			uint16 n = readmem16l(h->start + h->pos);
			h->pos += 2;
			return n;
		} else {
			h->pos += can_read;
			return EOF;
		}
	}
}
예제 #2
0
int test_oxm(FILE *f)
{
	int i, j;
	int hlen, npat, len, plen;
	int nins, nsmp;
	uint32 ilen;
	int slen[256];
	uint8 buf[1024];

	fseek(f, 0, SEEK_SET);
	if (fread(buf, 16, 1, f) < 16)
		return -1;
	if (memcmp(buf, "Extended Module:", 16))
		return -1;
	
	fseek(f, 60, SEEK_SET);
	hlen = read32l(f);
	fseek(f, 6, SEEK_CUR);
	npat = read16l(f);
	nins = read16l(f);

	if (npat > 256 || nins > 128)
		return -1;
	
	fseek(f, 60 + hlen, SEEK_SET);

	for (i = 0; i < npat; i++) {
		len = read32l(f);
		fseek(f, 3, SEEK_CUR);
		plen = read16l(f);
		fseek(f, len - 9 + plen, SEEK_CUR);
	}

	for (i = 0; i < nins; i++) {
		ilen = read32l(f);
		if (ilen > 263)
			return -1;
		fseek(f, -4, SEEK_CUR);
		fread(buf, ilen, 1, f);		/* instrument header */
		nsmp = readmem16l(buf + 27);

		if (nsmp > 255)
			return -1;
		if (nsmp == 0)
			continue;

		/* Read instrument data */
		for (j = 0; j < nsmp; j++) {
			slen[j] = read32l(f);
			fseek(f, 36, SEEK_CUR);
		}

		/* Read samples */
		for (j = 0; j < nsmp; j++) {
			read32b(f);
			if (read32b(f) == 0x4f676753)
				return 0;
			fseek(f, slen[j] - 8, SEEK_CUR);
		}
	}

	return -1;
}
예제 #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
int decrunch_oxm(FILE *f, FILE *fo)
{
	int i, j, pos;
	int hlen, npat, len, plen;
	int nins, nsmp;
	uint32 ilen;
	uint8 buf[1024];
	struct xm_instrument xi[256];
	char *pcm[256];
	int newlen = 0;

	fseek(f, 60, SEEK_SET);
	hlen = read32l(f);
	fseek(f, 6, SEEK_CUR);
	npat = read16l(f);
	nins = read16l(f);
	
	fseek(f, 60 + hlen, SEEK_SET);

	for (i = 0; i < npat; i++) {
		len = read32l(f);
		fseek(f, 3, SEEK_CUR);
		plen = read16l(f);
		fseek(f, len - 9 + plen, SEEK_CUR);
	}

	pos = ftell(f);
	fseek(f, 0, SEEK_SET);
	move_data(fo, f, pos);			/* module header + patterns */

	for (i = 0; i < nins; i++) {
		ilen = read32l(f);
		if (ilen > 1024)
			return -1;
		fseek(f, -4, SEEK_CUR);
		fread(buf, ilen, 1, f);		/* instrument header */
		buf[26] = 0;
		fwrite(buf, ilen, 1, fo);
		nsmp = readmem16l(buf + 27);

		if (nsmp == 0)
			continue;

		/* Read sample headers */
		for (j = 0; j < nsmp; j++) {
			xi[j].len = read32l(f);
			fread(xi[j].buf, 1, 36, f);
		}

		/* Read samples */
		for (j = 0; j < nsmp; j++) {
			if (xi[j].len > 0) {
				int res = 8;
				if (xi[j].buf[10] & 0x10)
					res = 16;
				pcm[j] = oggdec(f, xi[j].len, res, &newlen);
				xi[j].len = newlen;

				if (pcm[j] == NULL)
					return -1;
			}
		}

		/* Write sample headers */
		for (j = 0; j < nsmp; j++) {
			write32l(fo, xi[j].len);
			fwrite(xi[j].buf, 1, 36, fo);
		}

		/* Write samples */
		for (j = 0; j < nsmp; j++) {
			if (xi[j].len > 0) {
				fwrite(pcm[j], 1, xi[j].len, fo);
				free(pcm[j]);
			}
		}
	}

	return 0;
}