Exemplo n.º 1
0
static int mmd3_test(HIO_HANDLE *f, char *t, const int start)
{
	char id[4];
	uint32 offset, len;

	if (hio_read(id, 1, 4, f) < 4)
		return -1;

	if (memcmp(id, "MMD2", 4) && memcmp(id, "MMD3", 4))
		return -1;

	hio_seek(f, 28, SEEK_CUR);
	offset = hio_read32b(f);		/* expdata_offset */
	
	if (offset) {
		hio_seek(f, start + offset + 44, SEEK_SET);
		offset = hio_read32b(f);
		len = hio_read32b(f);
		hio_seek(f, start + offset, SEEK_SET);
		read_title(f, t, len);
	} else {
		read_title(f, t, 0);
	}

	return 0;
}
Exemplo n.º 2
0
static int read_abk_song(HIO_HANDLE *f, struct abk_song *song, uint32 songs_section_offset)
{
    int i;
    uint32 song_section;

    /* move to the start of the songs data section */
    hio_seek(f, songs_section_offset, SEEK_SET);

    if (hio_read16b(f) != 1)
    {
        /* we only support a single song.
         * in a an abk file for now */
        return -1;
    }

    song_section = hio_read32b(f);

    hio_seek(f, songs_section_offset + song_section, SEEK_SET);

    for (i=0; i<AMOS_ABK_CHANNELS; i++)
    {
        song->playlist_offset[i] = hio_read16b(f) + songs_section_offset + song_section;
    }

    song->tempo = hio_read16b(f);

    /* unused. just progress the file pointer forward */
    (void) hio_read16b(f);

    hio_read(song->song_name, 1, AMOS_STRING_LEN, f);

    return 0;
}
Exemplo n.º 3
0
static int mod_test(HIO_HANDLE *f, char *t, const int start)
{
    int i;
    char buf[4];

    hio_seek(f, start + 1080, SEEK_SET);
    if (hio_read(buf, 1, 4, f) < 4)
	return -1;

    if (!strncmp(buf + 2, "CH", 2) && isdigit((int)buf[0]) && isdigit((int)buf[1])) {
	i = (buf[0] - '0') * 10 + buf[1] - '0';
	if (i > 0 && i <= 32) {
	    goto found;
	}
    }

    if (!strncmp(buf + 1, "CHN", 3) && isdigit((int)*buf)) {
	if (*buf >= '0' && *buf <='9') {
	    goto found;
	}
    }

    if (memcmp(buf, "M.K.", 4))
	return -1;

  found:
    hio_seek(f, start + 0, SEEK_SET);
    read_title(f, t, 20);

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

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

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

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

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

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

	sub = &xxi->sub[0];

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

	xxs = &mod->xxs[smp_idx];

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

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

	return 0;
}
Exemplo n.º 5
0
static int s3m_test(HIO_HANDLE *f, char *t, const int start)
{
    hio_seek(f, start + 44, SEEK_SET);
    if (hio_read32b(f) != MAGIC_SCRM)
	return -1;

    hio_seek(f, start + 0, SEEK_SET);
    read_title(f, t, 28);

    return 0;
}
Exemplo n.º 6
0
Arquivo: load.c Projeto: visy/turha
static int load_module(xmp_context opaque, HIO_HANDLE *h, struct list_head *tmpfiles_list)
{
	struct context_data *ctx = (struct context_data *)opaque;
	struct module_data *m = &ctx->m;
	int i, ret;
	int test_result, load_result;

	load_prologue(ctx);

	D_(D_WARN "load");
	test_result = load_result = -1;
	for (i = 0; format_loader[i] != NULL; i++) {
		hio_seek(h, 0, SEEK_SET);
		test_result = format_loader[i]->test(h, NULL, 0);
		if (test_result == 0) {
			hio_seek(h, 0, SEEK_SET);
			D_(D_WARN "load format: %s", format_loader[i]->name);
			load_result = format_loader[i]->loader(m, h, 0);
			break;
		}
	}

	if (test_result == 0 && load_result == 0)
		set_md5sum(h, m->md5);

	hio_close(h);
	if (tmpfiles_list != NULL)
		unlink_tempfiles(tmpfiles_list);

	if (test_result < 0) {
		free(m->basename);
		free(m->dirname);
		return -XMP_ERROR_FORMAT;
	}

	if (load_result < 0) {
		xmp_release_module(opaque);
		return -XMP_ERROR_LOAD;
	}

	str_adj(m->mod.name);
	load_epilogue(ctx);

	ret = prepare_scan(ctx);
	if (ret < 0)
		return ret;

	scan_sequences(ctx);

	ctx->state = XMP_STATE_LOADED;

	return 0;
}
Exemplo n.º 7
0
Arquivo: load.c Projeto: kacmem/zxtune
static int composite_load(struct module_data *m, HIO_HANDLE *f, const int start)
{
  struct format_loader **loader;
  for (loader = format_loader; *loader; ++loader) {
    if (0 == (*loader)->test(f, 0, start)) {
      hio_seek(f, 0, SEEK_SET);
    	D_(D_WARN "load format: %s", (*loader)->name);
      return (*loader)->loader(m, f, start);
    }
    hio_seek(f, 0, SEEK_SET);
  }
  return -1;
}
Exemplo n.º 8
0
static int gdm_test(HIO_HANDLE *f, char *t, const int start)
{
	if (hio_read32b(f) != MAGIC_GDM)
		return -1;

	hio_seek(f, start + 0x47, SEEK_SET);
	if (hio_read32b(f) != MAGIC_GMFS)
		return -1;

	hio_seek(f, start + 4, SEEK_SET);
	libxmp_read_title(f, t, 32);

	return 0;
}
Exemplo n.º 9
0
static int hmn_test(HIO_HANDLE * f, char *t, const int start)
{
	int magic;

	hio_seek(f, start + 1080, SEEK_SET);
	magic = hio_read32b(f);

	if (magic != MAGIC_FEST && magic != MAGIC_MK)
		return -1;

	hio_seek(f, start + 0, SEEK_SET);
	read_title(f, t, 20);

	return 0;
}
Exemplo n.º 10
0
static int stc_test(HIO_HANDLE * f, char *t, const int start)
{
    int pos_ptr, orn_ptr, pat_ptr;
    int i, len, max_pat;

    hio_seek(f, start, SEEK_SET);

    if (hio_read8(f) > 0x20)			/* Check tempo */
        return -1;

    pos_ptr = hio_read16l(f);			/* Positions pointer */
    orn_ptr = hio_read16l(f);			/* Ornaments pointer */
    pat_ptr = hio_read16l(f);			/* Patterns pointer */

    if (pos_ptr < 138 || orn_ptr < 138 || pat_ptr < 138)
        return -1;

    hio_seek(f, start + pos_ptr, SEEK_SET);
    len = hio_read8(f) + 1;

    for (max_pat = i = 0; i < len; i++) {
        int pat = hio_read8(f);
        if (pat > MAX_PAT)		/* Check orders */
            return -1;
        if (pat > max_pat)
            max_pat = pat;
        hio_read8(f);
    }

    hio_seek(f, pat_ptr, SEEK_SET);

    for (i = 0; i < max_pat; i++) {
        int num = hio_read8(f);		/* Check track pointers */
        if (num != (i + 1))
            return -1;
        hio_read16l(f);
        hio_read16l(f);
        hio_read16l(f);
    }

    if (hio_read8(f) != 0xff)
        return -1;

    hio_seek(f, start + 7, SEEK_SET);
    read_title(f, t, 18);

    return 0;
}
Exemplo n.º 11
0
/**
 * @brief read the ABK playlist out from the file stream. This method malloc's some memory for the playlist
 * and can realloc if the playlist is very long.
 * @param f the stream to read from
 * @param playlist_offset the offset to the playlist sections.
 * @param playlist this structure is populated with the result.
 */
static void read_abk_playlist(HIO_HANDLE *f, uint32 playlist_offset, struct abk_playlist *playlist)
{
    uint16 playdata;
    int arraysize;

    arraysize = 64;

    /* clear the length */
    playlist->length = 0;

    /* move to the start of the songs data section. */
    hio_seek(f, playlist_offset, SEEK_SET);

    playlist->pattern = (uint16 *) malloc(arraysize * sizeof(uint16));

    playdata = hio_read16b(f);

    while((playdata != 0xFFFF) && (playdata != 0xFFFE))
    {
        /* i hate doing a realloc in a loop
           but i'd rather not traverse the list twice.*/

        if (playlist->length >= arraysize)
        {
            arraysize *= 2;
            playlist->pattern = (uint16 *) realloc(playlist->pattern , arraysize * sizeof(uint16));
        }

        playlist->pattern[playlist->length++] = playdata;
        playdata = hio_read16b(f);
    };
}
Exemplo n.º 12
0
static int pt3_test(HIO_HANDLE *f, char *t, const int start)
{
    if (hio_read32b(f) != MAGIC_FORM)
        return -1;

    hio_read32b(f);	/* skip size */

    if (hio_read32b(f) != MAGIC_MODL)
        return -1;

    if (hio_read32b(f) != MAGIC_VERS)
        return -1;

    hio_read32b(f);	/* skip size */

    hio_seek(f, 10, SEEK_CUR);

    if (hio_read32b(f) == MAGIC_INFO) {
        hio_read32b(f);	/* skip size */
        read_title(f, t, 32);
    } else {
        read_title(f, t, 0);
    }

    return 0;
}
Exemplo n.º 13
0
static int amd_test(HIO_HANDLE *f, char *t, const int start)
{
	char buf[9];

	hio_seek(f, start + 1062, SEEK_SET);
	if (hio_read(buf, 1, 9, f) < 9)
		return -1;

	if (memcmp(buf, "<o", 2) || memcmp(buf + 6, "RoR", 3))
		return -1;

	hio_seek(f, start + 0, SEEK_SET);
	libxmp_read_title(f, t, 24);

	return 0;
}
Exemplo n.º 14
0
static int sfx_test(HIO_HANDLE *f, char *t, const int start)
{
    uint32 a, b;

    hio_seek(f, 4 * 15, SEEK_CUR);
    a = hio_read32b(f);
    hio_seek(f, 4 * 15, SEEK_CUR);
    b = hio_read32b(f);

    if (a != MAGIC_SONG && b != MAGIC_SONG)
	return -1;

    read_title(f, t, 0);

    return 0;
}
Exemplo n.º 15
0
static int chip_test(HIO_HANDLE *f, char *t, const int start)
{
	char buf[4];

	hio_seek(f, start + 952, SEEK_SET);
	if (hio_read(buf, 1, 4, f) < 4)
		return -1;

	/* Also RASP? */
	if (memcmp(buf, "KRIS", 4) != 0)
		return -1;

	hio_seek(f, start + 0, SEEK_SET);
	read_title(f, t, 20);

	return 0;
}
Exemplo n.º 16
0
static int ssn_test(HIO_HANDLE *f, char *t, const int start)
{
    uint16 id;

    id = hio_read16b(f);
    if (id != 0x6966 && id != 0x4a4e)
	return -1;

    hio_seek(f, 238, SEEK_CUR);
    if (hio_read8(f) != 0xff)
	return -1;

    hio_seek(f, start + 2, SEEK_SET);
    read_title(f, t, 36);

    return 0;
}
Exemplo n.º 17
0
static int digi_test(HIO_HANDLE *f, char *t, const int start)
{
    char buf[20];

    if (hio_read(buf, 1, 20, f) < 20)
	return -1;

    if (memcmp(buf, "DIGI Booster module", 19))
	return -1;

    hio_seek(f, 156, SEEK_CUR);
    hio_seek(f, 3 * 4 * 32, SEEK_CUR);
    hio_seek(f, 2 * 1 * 32, SEEK_CUR);

    read_title(f, t, 32);

    return 0;
}
Exemplo n.º 18
0
static int mgt_test(HIO_HANDLE *f, char *t, const int start)
{
	int sng_ptr;

	if (hio_read24b(f) != MAGIC_MGT)
		return -1;
	hio_read8(f);
	if (hio_read32b(f) != MAGIC_MCS)
		return -1;

	hio_seek(f, 18, SEEK_CUR);
	sng_ptr = hio_read32b(f);
	hio_seek(f, start + sng_ptr, SEEK_SET);

	read_title(f, t, 32);
	
	return 0;
}
Exemplo n.º 19
0
Arquivo: load.c Projeto: kacmem/zxtune
static int composite_test(HIO_HANDLE *f, char *t, const int start)
{
  struct format_loader **loader;
  for (loader = format_loader; *loader; ++loader) {
    if (0 == (*loader)->test(f, t, start))
      return 0;
    hio_seek(f, 0, SEEK_SET);
  }
  return -1;
}
Exemplo n.º 20
0
static int dmf_test(HIO_HANDLE * f, char *t, const int start)
{
	if (hio_read32b(f) != MAGIC_DDMF)
		return -1;

	hio_seek(f, 9, SEEK_CUR);
	read_title(f, t, 30);

	return 0;
}
Exemplo n.º 21
0
static int stx_test(HIO_HANDLE *f, char *t, const int start)
{
    char buf[8];

    hio_seek(f, start + 20, SEEK_SET);
    if (hio_read(buf, 1, 8, f) < 8)
	return -1;
    if (memcmp(buf, "!Scream!", 8) && memcmp(buf, "BMOD2STM", 8))
	return -1;

    hio_seek(f, start + 60, SEEK_SET);
    if (hio_read(buf, 1, 4, f) < 4)
	return -1;
    if (memcmp(buf, "SCRM", 4))
	return -1;

    hio_seek(f, start + 0, SEEK_SET);
    read_title(f, t, 20);

    return 0;
}
Exemplo n.º 22
0
static int no_test(HIO_HANDLE *f, char *t, const int start)
{
	int nsize, pat, chn;
	int i;

	hio_seek(f, start, SEEK_CUR);

	if (hio_read32b(f) != 0x4e4f0000)		/* NO 0x00 0x00 */
		return -1;

	nsize = hio_read8(f);
	if (nsize != 20)
		return -1;

	/* test title */
	for (i = 0; i < nsize; i++) {
		if (hio_read8(f) == 0)
			return -1;
	}

	hio_seek(f, 9, SEEK_CUR);

	/* test number of patterns */
	pat = hio_read8(f);
	if (pat == 0)
		return -1;

	hio_read8(f);

	/* test number of channels */
	chn = hio_read8(f);
	if (chn <= 0 || chn > 16)
		return -1;

	hio_seek(f, start + 5, SEEK_SET);

	libxmp_read_title(f, t, nsize);

	return 0;
}
Exemplo n.º 23
0
int pw_wizardry(HIO_HANDLE *file_in, FILE *file_out, char **name)
{
	int in_size;
	uint8 *data;
	char title[21];
	int i;

	in_size = hio_size(file_in);

	/* printf ("input file size : %d\n", in_size); */
	if (in_size < MIN_FILE_LENGHT)
		return -2;

	/* alloc mem */
	data = (uint8 *)malloc (in_size + 4096);	/* slack added */
	if (data == NULL) {
		/*perror("Couldn't allocate memory");*/
		return -1;
	}
	hio_read(data, in_size, 1, file_in);


  /********************************************************************/
  /**************************   SEARCH   ******************************/
  /********************************************************************/

	for (i = 0; pw_format[i] != NULL; i++) {
		D_("checking format: %s", pw_format[i]->name);
		if (pw_format[i]->test(data, title, in_size) >= 0)
			break;
	}

	if (pw_format[i] == NULL) {
		free(data);
		return -1;
	}

	hio_seek(file_in, 0, SEEK_SET);
	if (pw_format[i]->depack(file_in, file_out) < 0) {
		free(data);
		return -1;
	}

	fflush(file_out);
	free(data);

	if (name != NULL) {
		*name = pw_format[i]->name;
	}

	return 0;
}
Exemplo n.º 24
0
static int stm_test(HIO_HANDLE *f, char *t, const int start)
{
    char buf[8];

    hio_seek(f, start + 20, SEEK_SET);
    if (hio_read(buf, 1, 8, f) < 8)
	return -1;
    if (memcmp(buf, "!Scream!", 8) && memcmp(buf, "BMOD2STM", 8))
	return -1;

    hio_read8(f);

    if (hio_read8(f) != STM_TYPE_MODULE)
	return -1;

    if (hio_read8(f) < 1)		/* We don't want STX files */
	return -1;

    hio_seek(f, start + 0, SEEK_SET);
    read_title(f, t, 20);

    return 0;
}
Exemplo n.º 25
0
static int get_inst_cnt(struct module_data *m, int size, HIO_HANDLE *f, void *parm)
{
	struct xmp_module *mod = &m->mod;
	int i;

	hio_read8(f);			/* 00 */
	i = hio_read8(f) + 1;		/* instrument number */
	
	if (i > mod->ins)
		mod->ins = i;

	hio_seek(f, 28, SEEK_CUR);		/* skip name */

	mod->smp += hio_read8(f);

	return 0;
}
Exemplo n.º 26
0
Arquivo: load.c Projeto: Nlcke/gideros
static void set_md5sum(HIO_HANDLE *f, unsigned char *digest)
{
	unsigned char buf[BUFLEN];
	MD5_CTX ctx;
	int bytes_read;

	if (hio_size(f) <= 0) {
		memset(digest, 0, 16);
		return;
	}

	hio_seek(f, 0, SEEK_SET);

	MD5Init(&ctx);
	while ((bytes_read = hio_read(buf, 1, BUFLEN, f)) > 0) {
		MD5Update(&ctx, buf, bytes_read);
	}
	MD5Final(digest, &ctx);
}
Exemplo n.º 27
0
static int okt_load(struct module_data *m, HIO_HANDLE * f, const int start)
{
    iff_handle handle;
    struct local_data data;
    int ret;

    LOAD_INIT();

    hio_seek(f, 8, SEEK_CUR);	/* OKTASONG */

    handle = iff_new();
    if (handle == NULL)
        return -1;

    memset(&data, 0, sizeof(struct local_data));

    /* IFF chunk IDs */
    ret = iff_register(handle, "CMOD", get_cmod);
    ret |= iff_register(handle, "SAMP", get_samp);
    ret |= iff_register(handle, "SPEE", get_spee);
    ret |= iff_register(handle, "SLEN", get_slen);
    ret |= iff_register(handle, "PLEN", get_plen);
    ret |= iff_register(handle, "PATT", get_patt);
    ret |= iff_register(handle, "PBOD", get_pbod);
    ret |= iff_register(handle, "SBOD", get_sbod);

    if (ret != 0)
        return -1;

    set_type(m, "Oktalyzer");

    MODULE_INFO();

    /* Load IFF chunks */
    if (iff_load(handle, m, f, &data) < 0) {
        iff_release(handle);
        return -1;
    }

    iff_release(handle);

    return 0;
}
Exemplo n.º 28
0
Arquivo: load.c Projeto: kacmem/zxtune
static int module_load(HIO_HANDLE* h, struct context_data *ctx, const struct format_loader* format)
{
	struct module_data *m = &ctx->m;

	hio_seek(h, 0, SEEK_SET);
	if (format->loader(m, h, 0) < 0)
	  return -XMP_ERROR_LOAD;

	str_adj(m->mod.name);
	str_adj(m->mod.author);

	load_epilogue(ctx);

	if (prepare_scan(ctx) < 0)
	  return -XMP_ERROR_LOAD;

	scan_sequences(ctx);
	ctx->state = XMP_STATE_LOADED;
	set_md5sum(h, m->md5);
	return 0;
}
Exemplo n.º 29
0
static int hsc_test(HIO_HANDLE *f, char *t, const int start)
{
    int p, i, r, c;
    uint8 buf[1200];

    hio_seek(f, 128 * 12, SEEK_CUR);

    if (hio_read(buf, 1, 51, f) != 51)
	return -1;

    for (p = i = 0; i < 51; i++) {
	if (buf[i] == 0xff)
	    break;
	if (buf[i] > p)
	    p = buf[i];
    }
    if (!i || !p || i > 50 || p > 50)		/* Test number of patterns */
	return -1;		

    for (i = 0; i < p; i++) {
	hio_read(buf, 1, 64 * 9 * 2, f);
	for (r = 0; r < 64; r++) {
	    for (c = 0; c < 9; c++) {
		uint8 n = buf[r * 9 * 2 + c * 2];
		uint8 m = buf[r * 9 * 2 + c * 2 + 1];
		if (m > 0x06 && m < 0x10 && n != 0x80)	/* Test effects 07..0f */
		    return -1;
		if (MSN(m) > 6 && MSN(m) < 10)	/* Test effects 7x .. 9x */
		    return -1;
	    }
	}
    }

    libxmp_read_title(f, t, 0);

    return 0;
}
Exemplo n.º 30
0
Arquivo: sample.c Projeto: visy/turha
int load_sample(struct module_data *m, HIO_HANDLE *f, int flags, struct xmp_sample *xxs, void *buffer)
{
	int bytelen, extralen, unroll_extralen, i;

	/* Adlib FM patches */
	if (flags & SAMPLE_FLAG_ADLIB) {
		const int size = 11;

		if (flags & SAMPLE_FLAG_HSC) {
			convert_hsc_to_sbi(buffer);
		}

		xxs->data = malloc(size + 4);
		if (xxs->data == NULL)
			return -1;

		*(uint32 *)xxs->data = 0;
		xxs->data += 4;

		memcpy(xxs->data, buffer, size);

		xxs->flg |= XMP_SAMPLE_SYNTH;
		xxs->len = size;

		return 0;
	}

	/* Empty samples
	 */
	if (xxs->len == 0) {
		return 0;
	}

	/* Skip sample loading
	 * FIXME: fails for ADPCM samples
	 */
	if (m && m->smpctl & XMP_SMPCTL_SKIP) {
		if (~flags & SAMPLE_FLAG_NOLOAD)
			hio_seek(f, xxs->len, SEEK_CUR);
		return 0;
	}

	/* Loop parameters sanity check
	 */
	if (xxs->lpe > xxs->len) {
		xxs->lpe = xxs->len;
	}
	if (xxs->lps >= xxs->len || xxs->lps >= xxs->lpe) {
		xxs->lps = xxs->lpe = 0;
		xxs->flg &= ~(XMP_SAMPLE_LOOP | XMP_SAMPLE_LOOP_BIDIR);
	}

	/* Patches with samples
	 * Allocate extra sample for interpolation.
	 */
	bytelen = xxs->len;
	extralen = 4;
	unroll_extralen = 0;

	/* Disable birectional loop flag if sample is not looped
	 */
	if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
		if (~xxs->flg & XMP_SAMPLE_LOOP)
			xxs->flg &= ~XMP_SAMPLE_LOOP_BIDIR;
	}
	/* Unroll bidirectional loops
	 */
	if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) {
		unroll_extralen = (xxs->lpe - xxs->lps) -
				(xxs->len - xxs->lpe);

		if (unroll_extralen < 0) {
			unroll_extralen = 0;
		}
	}

	if (xxs->flg & XMP_SAMPLE_16BIT) {
		bytelen *= 2;
		extralen *= 2;
		unroll_extralen *= 2;
	}

	/* add guard bytes before the buffer for higher order interpolation */
	xxs->data = malloc(bytelen + extralen + unroll_extralen + 4);
	if (xxs->data == NULL)
		return -1;

	*(uint32 *)xxs->data = 0;
	xxs->data += 4;

	if (flags & SAMPLE_FLAG_NOLOAD) {
		memcpy(xxs->data, buffer, bytelen);
	} else {
		uint8 buf[5];
		long pos = hio_tell(f);
		int num = hio_read(buf, 1, 5, f);

		hio_seek(f, pos, SEEK_SET);

		if (num == 5 && !memcmp(buf, "ADPCM", 5)) {
			int x2 = bytelen >> 1;
			char table[16];

			hio_seek(f, 5, SEEK_CUR);	/* Skip "ADPCM" */
			hio_read(table, 1, 16, f);
			hio_read(xxs->data + x2, 1, x2, f);
			adpcm4_decoder((uint8 *)xxs->data + x2,
				       (uint8 *)xxs->data, table, bytelen);
		} else {