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; } } }
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; }
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; }
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; }