示例#1
0
static int it_ptm_read_sample_header(IT_SAMPLE *sample, long *offset, DUMBFILE *f)
{
	int flags;

	flags = dumbfile_getc(f);

    dumbfile_getnc((char *)sample->filename, 12, f);
	sample->filename[12] = 0;

	sample->default_volume = dumbfile_getc(f);

	sample->C5_speed = dumbfile_igetw(f) << 1;

	dumbfile_skip(f, 2); /* segment */

	*offset = dumbfile_igetl(f);

	sample->length = dumbfile_igetl(f);
	sample->loop_start = dumbfile_igetl(f);
	sample->loop_end = dumbfile_igetl(f);

	/* GUSBegin, GUSLStart, GUSLEnd, GUSLoop, reserverd */
	dumbfile_skip(f, 4+4+4+1+1);

    dumbfile_getnc((char *)sample->name, 28, f);
	sample->name[28] = 0;

	/*
	if (dumbfile_mgetl(f) != DUMB_ID('P','T','M','S'))
		return -1;
	*/

	/* BLAH! Shit likes to have broken or missing sample IDs */
	dumbfile_skip(f, 4);

	if ((flags & 3) == 0) {
		/* Looks like no sample */
		sample->flags &= ~IT_SAMPLE_EXISTS;
		return dumbfile_error(f);
	}

	sample->global_volume = 64;

	sample->flags = IT_SAMPLE_EXISTS;
	if (flags & 4) sample->flags |= IT_SAMPLE_LOOP;
	if (flags & 8) sample->flags |= IT_SAMPLE_PINGPONG_LOOP;

	if (flags & 16) {
		sample->flags |= IT_SAMPLE_16BIT;

		sample->length >>= 1;
		sample->loop_start >>= 1;
		sample->loop_end >>= 1;
	}
示例#2
0
static int readblock(DUMBFILE *f)
{
	long size;
	int c;

	size = dumbfile_igetw(f);
	if (size < 0)
		return size;

	sourcebuf = malloc(size);
	if (!sourcebuf)
		return -1;

	c = dumbfile_getnc((char *)sourcebuf, size, f);
	if (c < size) {
		free(sourcebuf);
		sourcebuf = NULL;
		return -1;
	}

	sourcepos = sourcebuf;
	sourceend = sourcebuf + size;
	rembits = 8;
	return 0;
}
示例#3
0
文件: readxm.c 项目: codefoco/dumb
static int limit_xm_resize(void *f, long n) {
    DUMBFILE *df = f;
    LIMITED_XM *lx = df->file;
    if (n < 0)
        return -1;
    if (lx->buffered || n) {
        if (n > lx->allocated) {
            unsigned char *buffered = realloc(lx->buffered, n);
            if (!buffered)
                return -1;
            lx->buffered = buffered;
            memset(buffered + lx->allocated, 0, n - lx->allocated);
            lx->allocated = n;
        }
        if (dumbfile_getnc((char *)lx->buffered, n, lx->remaining) < n)
            return -1;
    } else if (!n) {
        if (lx->buffered)
            free(lx->buffered);
        lx->buffered = NULL;
        lx->allocated = 0;
    }
    lx->limit = n;
    lx->ptr = 0;
    return 0;
}
示例#4
0
文件: itread.c 项目: Altazimuth/SLADE
static int readblock(DUMBFILE *f, readblock_crap * crap)
{
	long size;
	int c;

	size = dumbfile_igetw(f);
	if (size < 0)
		return (int)size;

	crap->sourcebuf = malloc(size);
	if (!crap->sourcebuf)
		return -1;

	c = (int)dumbfile_getnc((char *)crap->sourcebuf, size, f);
	if (c < size) {
		free(crap->sourcebuf);
		crap->sourcebuf = NULL;
		return -1;
	}

	crap->sourcepos = crap->sourcebuf;
	crap->sourceend = crap->sourcebuf + size;
	crap->rembits = 8;
	return 0;
}
示例#5
0
文件: readasy.c 项目: AkumaKing/Xeu
static int it_asy_read_pattern( IT_PATTERN *pattern, DUMBFILE *f, unsigned char *buffer )
{
	int pos;
	int channel;
	int row;
	IT_ENTRY *entry;

	pattern->n_rows = 64;

	if ( dumbfile_getnc( buffer, 64 * 8 * 4, f ) != 64 * 8 * 4 )
		return -1;

	/* compute number of entries */
	pattern->n_entries = 64; /* Account for the row end markers */
	pos = 0;
	for ( row = 0; row < 64; ++row ) {
		for ( channel = 0; channel < 8; ++channel ) {
			if ( buffer[ pos + 0 ] | buffer[ pos + 1 ] | buffer[ pos + 2 ] | buffer[ pos + 3 ] )
				++pattern->n_entries;
			pos += 4;
		}
	}

	pattern->entry = malloc( pattern->n_entries * sizeof( *pattern->entry ) );
	if ( !pattern->entry )
		return -1;

	entry = pattern->entry;
	pos = 0;
	for ( row = 0; row < 64; ++row ) {
		for ( channel = 0; channel < 8; ++channel ) {
			if ( buffer[ pos + 0 ] | buffer[ pos + 1 ] | buffer[ pos + 2 ] | buffer[ pos + 3 ] ) {
				entry->channel = channel;
				entry->mask = 0;

				if ( buffer[ pos + 0 ] && buffer[ pos + 0 ] < 96 ) {
					entry->note = buffer[ pos + 0 ];
					entry->mask |= IT_ENTRY_NOTE;
				}

				if ( buffer[ pos + 1 ] && buffer[ pos + 1 ] <= 64 ) {
					entry->instrument = buffer[ pos + 1 ];
					entry->mask |= IT_ENTRY_INSTRUMENT;
				}

				_dumb_it_xm_convert_effect( buffer[ pos + 2 ], buffer[ pos + 3 ], entry, 1 );

				if ( entry->mask ) ++entry;
			}
			pos += 4;
		}
		IT_SET_END_ROW( entry );
		++entry;
	}

	pattern->n_entries = (int)(entry - pattern->entry);

	return 0;
}
示例#6
0
文件: readasy.c 项目: codefoco/dumb
static int it_asy_read_sample_header(IT_SAMPLE *sample, DUMBFILE *f) {
    int finetune, key_offset;

    /**
         21       22   Chars     Sample 1 name.  If the name is not a full
                                 22 chars in length, it will be null
                                 terminated.

    If
    the sample name begins with a '#' character (ASCII $23 (35)) then this is
    assumed not to be an instrument name, and is probably a message.
    */
    dumbfile_getnc((char *)sample->name, 22, f);
    sample->name[22] = 0;

    sample->filename[0] = 0;

    /** Each  finetune step changes  the note 1/8th  of  a  semitone. */
    finetune = (signed char)(dumbfile_getc(f) << 4) >> 4; /* signed nibble */
    sample->default_volume =
        dumbfile_getc(f); // Should we be setting global_volume to this instead?
    sample->global_volume = 64;
    if (sample->default_volume > 64)
        sample->default_volume = 64;
    key_offset = (signed char)dumbfile_getc(f); /* base key offset */
    sample->length = dumbfile_igetl(f);
    sample->loop_start = dumbfile_igetl(f);
    sample->loop_end = sample->loop_start + dumbfile_igetl(f);

    if (sample->length <= 0) {
        sample->flags = 0;
        return 0;
    }

    sample->flags = IT_SAMPLE_EXISTS;

    sample->default_pan = 0;
    sample->C5_speed =
        (int)(AMIGA_CLOCK / 214.0 *
              pow(DUMB_SEMITONE_BASE, key_offset)); //( long )( 16726.0 * pow(
                                                    // DUMB_PITCH_BASE, finetune
                                                    //* 32 ) );
    sample->finetune = finetune * 32;
    // the above line might be wrong

    if ((sample->loop_end - sample->loop_start > 2) &&
        (sample->loop_end <= sample->length))
        sample->flags |= IT_SAMPLE_LOOP;

    sample->vibrato_speed = 0;
    sample->vibrato_depth = 0;
    sample->vibrato_rate = 0;
    sample->vibrato_waveform = 0; // do we have to set _all_ these?
    sample->max_resampling_quality = -1;

    return dumbfile_error(f);
}
示例#7
0
/* I (entheh) have two XM files saved by a very naughty program. After a
 * 16-bit sample, it saved a rogue byte. The length of the sample was indeed
 * an odd number, incremented to include the rogue byte.
 *
 * In this function we are converting sample lengths and loop points so they
 * are measured in samples. This means we forget about the extra bytes, and
 * they don't get skipped. So we fail trying to read the next instrument.
 *
 * To get around this, this function returns the number of rogue bytes that
 * won't be accounted for by reading sample->length samples. It returns a
 * negative number on failure.
 */
static int it_xm_read_sample_header(IT_SAMPLE *sample, DUMBFILE *f)
{
	int type;
	int relative_note_number; /* relative to C4 */
	int finetune;
	int roguebytes;
	int roguebytesmask;
	int reserved;

	sample->length         = dumbfile_igetl(f);
	sample->loop_start     = dumbfile_igetl(f);
	sample->loop_end       = sample->loop_start + dumbfile_igetl(f);
	sample->global_volume  = 64;
	sample->default_volume = dumbfile_getc(f);
	finetune               = (signed char)dumbfile_getc(f); /* -128..127 <=> -1 semitone .. +127/128 of a semitone */
	type                   = dumbfile_getc(f);
	sample->default_pan    = dumbfile_getc(f); /* 0-255 */
	relative_note_number   = (signed char)dumbfile_getc(f);

	reserved = dumbfile_getc(f);

    dumbfile_getnc((char *)sample->name, 22, f);
	sample->name[22] = 0;
    trim_whitespace((char *)sample->name, 22);

	sample->filename[0] = 0;

	if (dumbfile_error(f))
		return -1;

	sample->C5_speed = (long)(16726.0*pow(DUMB_SEMITONE_BASE, relative_note_number) /**pow(DUMB_PITCH_BASE, )*/ );
	sample->finetune = finetune*2;

	sample->flags = IT_SAMPLE_EXISTS;

	if (reserved == 0xAD &&
		(!(type & (XM_SAMPLE_16BIT | XM_SAMPLE_STEREO))))
	{
		/* F U Olivier Lapicque */
		roguebytes = 4;
		roguebytesmask = 4 << 2;
	}
	else
	{
		roguebytes = (int)sample->length;
		roguebytesmask = 3;
	}

	if (type & XM_SAMPLE_16BIT) {
		sample->flags |= IT_SAMPLE_16BIT;
		sample->length >>= 1;
		sample->loop_start >>= 1;
		sample->loop_end >>= 1;
	} else
示例#8
0
/* I (entheh) have two XM files saved by a very naughty program. After a
 * 16-bit sample, it saved a rogue byte. The length of the sample was indeed
 * an odd number, incremented to include the rogue byte.
 *
 * In this function we are converting sample lengths and loop points so they
 * are measured in samples. This means we forget about the extra bytes, and
 * they don't get skipped. So we fail trying to read the next instrument.
 *
 * To get around this, this function returns the number of rogue bytes that
 * won't be accounted for by reading sample->length samples. It returns a
 * negative number on failure.
 */
static int it_xm_read_sample_header(IT_SAMPLE *sample, DUMBFILE *f)
{
	int type;
	int relative_note_number; /* relative to C4 */
	int finetune;
	int roguebytes;
	int roguebytesmask;

	sample->length         = dumbfile_igetl(f);
	sample->loop_start     = dumbfile_igetl(f);
	sample->loop_end       = sample->loop_start + dumbfile_igetl(f);
	sample->global_volume  = 64;
	sample->default_volume = dumbfile_getc(f);
	finetune               = (signed char)dumbfile_getc(f); /* -128..127 <=> -1 semitone .. +127/128 of a semitone */
	type                   = dumbfile_getc(f);
	sample->default_pan    = dumbfile_getc(f); /* 0-255 */
	relative_note_number   = (signed char)dumbfile_getc(f);

	dumbfile_skip(f, 1);  /* reserved */

	dumbfile_getnc(sample->name, 22, f);
	sample->name[22] = 0;

	sample->filename[0] = 0;

	if (dumbfile_error(f))
		return -1;

	sample->C5_speed = (long)(16726.0*pow(DUMB_SEMITONE_BASE, relative_note_number)*pow(DUMB_PITCH_BASE, finetune*2));

	sample->flags = IT_SAMPLE_EXISTS;

	roguebytes = (int)sample->length;
	roguebytesmask = 3;

	if (type & XM_SAMPLE_16BIT) {
		sample->flags |= IT_SAMPLE_16BIT;
		sample->length >>= 1;
		sample->loop_start >>= 1;
		sample->loop_end >>= 1;
	} else
示例#9
0
/* dumb_read_riff_quick(): reads a RIFF file into a DUH struct, returning a
 * pointer to the DUH struct. When you have finished with it, you must pass
 * the pointer to unload_duh() so that the memory can be freed.
 */
DUH *dumb_read_riff_quick( DUMBFILE * f )
{
	DUH * duh;
	struct riff * stream;

	{
		unsigned char * buffer = 0;
		unsigned size = 0;
		unsigned read;
		do
		{
			buffer = realloc( buffer, 32768 + size );
			if ( ! buffer ) return 0;
			read = dumbfile_getnc( buffer + size, 32768, f );
			if ( read < 0 )
			{
				free( buffer );
				return 0;
			}
			size += read;
		}
		while ( read == 32768 );
		stream = riff_parse( buffer, size, 1 );
		if ( ! stream ) stream = riff_parse( buffer, size, 0 );
		free( buffer );
	}

	if ( ! stream ) return 0;

	if ( stream->type == DUMB_ID( 'A', 'M', ' ', ' ' ) )
		duh = dumb_read_riff_am( stream );
	else if ( stream->type == DUMB_ID( 'A', 'M', 'F', 'F' ) )
		duh = dumb_read_riff_amff( stream );
	else if ( stream->type == DUMB_ID( 'D', 'S', 'M', 'F' ) )
		duh = dumb_read_riff_dsmf( stream );
	else duh = 0;

	riff_free( stream );

	return duh;
}
示例#10
0
static void *sequence_load_signal(DUH *duh, DUMBFILE *file)
{
    long size;
    unsigned char *signal;

    (void)duh;

    size = dumbfile_igetl(file);
    if (dumbfile_error(file) || size <= 0)
        return NULL;

    signal = malloc(size);
    if (!signal)
        return NULL;

    if (dumbfile_getnc((char *)signal, size, file) < size) {
        free(signal);
        return NULL;
    }

    return signal;
}
示例#11
0
文件: readasy.c 项目: codefoco/dumb
static int it_asy_read_sample_data(IT_SAMPLE *sample, DUMBFILE *f) {
    long truncated_size;

    /* let's get rid of the sample data coming after the end of the loop */
    if ((sample->flags & IT_SAMPLE_LOOP) && sample->loop_end < sample->length) {
        truncated_size = sample->length - sample->loop_end;
        sample->length = sample->loop_end;
    } else {
        truncated_size = 0;
    }

    sample->data = malloc(sample->length);

    if (!sample->data)
        return -1;

    if (sample->length)
        dumbfile_getnc(sample->data, sample->length, f);

    dumbfile_skip(f, truncated_size);

    return dumbfile_error(f);
}
示例#12
0
static DUMB_IT_SIGDATA *it_okt_load_sigdata(DUMBFILE *f)
{
	DUMB_IT_SIGDATA *sigdata;
	unsigned n_channels;
	unsigned i, j, k, l;
	IFF_CHUNKED *mod;
	const IFF_CHUNK *chunk;

	char signature[8];

	if (dumbfile_getnc(signature, 8, f) < 8 ||
		memcmp(signature, "OKTASONG", 8)) {
		return NULL;
	}

	mod = dumbfile_read_okt(f);
	if (!mod)
		return NULL;

	sigdata = (DUMB_IT_SIGDATA *) malloc(sizeof(*sigdata));
	if (!sigdata) {
		free_okt(mod);
		return NULL;
	}

	sigdata->name[0] = 0;

	chunk = get_chunk_by_type(mod, DUMB_ID('S','P','E','E'), 0);
	if (!chunk || chunk->size < 2) {
		free(sigdata);
		free_okt(mod);
		return NULL;
	}

	sigdata->speed = (chunk->data[0] << 8) | chunk->data[1];

	chunk = get_chunk_by_type(mod, DUMB_ID('S','A','M','P'), 0);
	if (!chunk || chunk->size < 32) {
		free(sigdata);
		free_okt(mod);
		return NULL;
	}

	sigdata->n_samples = chunk->size / 32;

	chunk = get_chunk_by_type(mod, DUMB_ID('C','M','O','D'), 0);
	if (!chunk || chunk->size < 8) {
		free(sigdata);
		free_okt(mod);
		return NULL;
	}

	n_channels = 0;

	for (i = 0; i < 4; i++) {
		j = (chunk->data[i * 2] << 8) | chunk->data[i * 2 + 1];
		if (!j) n_channels++;
		else if (j == 1) n_channels += 2;
	}

	if (!n_channels) {
		free(sigdata);
		free_okt(mod);
		return NULL;
	}

	sigdata->n_pchannels = n_channels;

	sigdata->sample = (IT_SAMPLE *) malloc(sigdata->n_samples * sizeof(*sigdata->sample));
	if (!sigdata->sample) {
		free(sigdata);
		free_okt(mod);
		return NULL;
	}

	sigdata->song_message = NULL;
	sigdata->order = NULL;
	sigdata->instrument = NULL;
	sigdata->pattern = NULL;
	sigdata->midi = NULL;
	sigdata->checkpoint = NULL;

	sigdata->n_instruments = 0;

	for (i = 0; i < (unsigned)sigdata->n_samples; i++)
		sigdata->sample[i].data = NULL;

	chunk = get_chunk_by_type(mod, DUMB_ID('S','A','M','P'), 0);

	for (i = 0; i < (unsigned)sigdata->n_samples; i++) {
		it_okt_read_sample_header(&sigdata->sample[i], chunk->data + 32 * i);
	}

	sigdata->restart_position = 0;

	chunk = get_chunk_by_type(mod, DUMB_ID('P','L','E','N'), 0);
	if (!chunk || chunk->size < 2) {
		_dumb_it_unload_sigdata(sigdata);
		free_okt(mod);
		return NULL;
	}

	sigdata->n_orders = (chunk->data[0] << 8) | chunk->data[1];
	// what if this is > 128?

	if (sigdata->n_orders <= 0 || sigdata->n_orders > 128) {
		_dumb_it_unload_sigdata(sigdata);
		free_okt(mod);
		return NULL;
	}

	chunk = get_chunk_by_type(mod, DUMB_ID('P','A','T','T'), 0);
	if (!chunk || chunk->size < (unsigned)sigdata->n_orders) {
		_dumb_it_unload_sigdata(sigdata);
		free_okt(mod);
		return NULL;
	}

	sigdata->order = (unsigned char *) malloc(sigdata->n_orders);
	if (!sigdata->order) {
		_dumb_it_unload_sigdata(sigdata);
		free_okt(mod);
		return NULL;
	}

	memcpy(sigdata->order, chunk->data, sigdata->n_orders);

	/* Work out how many patterns there are. */
	chunk = get_chunk_by_type(mod, DUMB_ID('S','L','E','N'), 0);
	if (!chunk || chunk->size < 2) {
		_dumb_it_unload_sigdata(sigdata);
		free_okt(mod);
		return NULL;
	}

	sigdata->n_patterns = (chunk->data[0] << 8) | chunk->data[1];

	j = get_chunk_count(mod, DUMB_ID('P','B','O','D'));
	if (sigdata->n_patterns > (int)j) sigdata->n_patterns = (int)j;

	if (!sigdata->n_patterns) {
		_dumb_it_unload_sigdata(sigdata);
		free_okt(mod);
		return NULL;
	}

	sigdata->pattern = (IT_PATTERN *) malloc(sigdata->n_patterns * sizeof(*sigdata->pattern));
	if (!sigdata->pattern) {
		_dumb_it_unload_sigdata(sigdata);
		free_okt(mod);
		return NULL;
	}
	for (i = 0; i < (unsigned)sigdata->n_patterns; i++)
		sigdata->pattern[i].entry = NULL;

	/* Read in the patterns */
	for (i = 0; i < (unsigned)sigdata->n_patterns; i++) {
		chunk = get_chunk_by_type(mod, DUMB_ID('P','B','O','D'), i);
		if (it_okt_read_pattern(&sigdata->pattern[i], chunk->data, chunk->size, n_channels) != 0) {
			_dumb_it_unload_sigdata(sigdata);
			free_okt(mod);
			return NULL;
		}
	}

	/* And finally, the sample data */
	k = get_chunk_count(mod, DUMB_ID('S','B','O','D'));
	for (i = 0, j = 0; i < (unsigned)sigdata->n_samples && j < k; i++) {
		if (sigdata->sample[i].flags & IT_SAMPLE_EXISTS) {
			chunk = get_chunk_by_type(mod, DUMB_ID('S','B','O','D'), j);
			if (it_okt_read_sample_data(&sigdata->sample[i], (const char *)chunk->data, chunk->size)) {
				_dumb_it_unload_sigdata(sigdata);
				free_okt(mod);
				return NULL;
			}
			j++;
		}
	}
	for (; i < (unsigned)sigdata->n_samples; i++) {
		sigdata->sample[i].flags = 0;
	}

	chunk = get_chunk_by_type(mod, DUMB_ID('C','M','O','D'), 0);

	for (i = 0, j = 0; i < n_channels && j < 4; j++) {
		k = (chunk->data[j * 2] << 8) | chunk->data[j * 2 + 1];
		l = (j == 1 || j == 2) ? 48 : 16;
		if (k == 0) {
			sigdata->channel_pan[i++] = l;
		}
		else if (k == 1) {
			sigdata->channel_pan[i++] = l;
			sigdata->channel_pan[i++] = l;
		}
	}

	free_okt(mod);

	/* Now let's initialise the remaining variables, and we're done! */
	sigdata->flags = IT_WAS_AN_OKT | IT_WAS_AN_XM | IT_WAS_A_MOD | IT_OLD_EFFECTS | IT_COMPATIBLE_GXX | IT_STEREO;

	sigdata->global_volume = 128;
	sigdata->mixing_volume = 48;
	/* We want 50 ticks per second; 50/6 row advances per second;
	 * 50*10=500 row advances per minute; 500/4=125 beats per minute.
	 */
	sigdata->tempo = 125;
	sigdata->pan_separation = 128;

	memset(sigdata->channel_volume, 64, DUMB_IT_N_CHANNELS);
	memset(sigdata->channel_pan + n_channels, 32, DUMB_IT_N_CHANNELS - n_channels);

	_dumb_it_fix_invalid_orders(sigdata);

	return sigdata;
}
示例#13
0
static IFF_CHUNKED *dumbfile_read_okt(DUMBFILE *f)
{
	IFF_CHUNKED *mod = (IFF_CHUNKED *) malloc(sizeof(*mod));
	if (!mod) return NULL;

	mod->chunk_count = 0;
	mod->chunks = 0;

	for (;;)
	{
		long bytes_read;
		IFF_CHUNK * chunk = ( IFF_CHUNK * ) realloc( mod->chunks, ( mod->chunk_count + 1 ) * sizeof( IFF_CHUNK ) );
		if ( !chunk )
		{
			if ( mod->chunks ) free( mod->chunks );
			free( mod );
			return NULL;
		}
		mod->chunks = chunk;
		chunk += mod->chunk_count;

		bytes_read = dumbfile_mgetl( f );
		if ( bytes_read < 0 ) break;

		chunk->type = bytes_read;
		chunk->size = dumbfile_mgetl( f );

		if ( dumbfile_error( f ) ) break;

		chunk->data = (unsigned char *) malloc( chunk->size );
		if ( !chunk->data )
		{
			free( mod->chunks );
			free( mod );
			return NULL;
		}

		bytes_read = dumbfile_getnc( ( char * ) chunk->data, chunk->size, f );
		if ( bytes_read < (long)chunk->size )
		{
			if ( bytes_read <= 0 ) {
				free( chunk->data );
				break;
			} else {
				chunk->size = bytes_read;
				mod->chunk_count++;
				break;
			}
		}

		mod->chunk_count++;
	}

	if ( !mod->chunk_count ) {
		if ( mod->chunks ) free(mod->chunks);
		free(mod);
		mod = NULL;
	}

	return mod;
}
示例#14
0
文件: readany.c 项目: codefoco/dumb
DUH *dumb_read_any_quick(DUMBFILE *f, int restrict_, int subsong) {
    unsigned char signature[maximum_signature_size];
    unsigned long signature_size;
    DUH *duh = NULL;

    /* signature_size = dumbfile_get_size(f); */

    signature_size =
        dumbfile_getnc((char *)signature, maximum_signature_size, f);
    dumbfile_seek(f, 0, DFS_SEEK_SET);

    if (signature_size >= 4 && signature[0] == 'I' && signature[1] == 'M' &&
        signature[2] == 'P' && signature[3] == 'M') {
        duh = dumb_read_it_quick(f);
    } else if (signature_size >= 17 &&
               !memcmp(signature, "Extended Module: ", 17)) {
        duh = dumb_read_xm_quick(f);
    } else if (signature_size >= 0x30 && signature[0x2C] == 'S' &&
               signature[0x2D] == 'C' && signature[0x2E] == 'R' &&
               signature[0x2F] == 'M') {
        duh = dumb_read_s3m_quick(f);
    } else if (signature_size >= 30 &&
               /*signature[28] == 0x1A &&*/ signature[29] == 2 &&
               (!strnicmp((const char *)signature + 20, "!Scream!", 8) ||
                !strnicmp((const char *)signature + 20, "BMOD2STM", 8) ||
                !strnicmp((const char *)signature + 20, "WUZAMOD!", 8))) {
        duh = dumb_read_stm_quick(f);
    } else if (signature_size >= 2 &&
               ((signature[0] == 0x69 && signature[1] == 0x66) ||
                (signature[0] == 0x4A && signature[1] == 0x4E))) {
        duh = dumb_read_669_quick(f);
    } else if (signature_size >= 0x30 && signature[0x2C] == 'P' &&
               signature[0x2D] == 'T' && signature[0x2E] == 'M' &&
               signature[0x2F] == 'F') {
        duh = dumb_read_ptm_quick(f);
    } else if (signature_size >= 4 && signature[0] == 'P' &&
               signature[1] == 'S' && signature[2] == 'M' &&
               signature[3] == ' ') {
        duh = dumb_read_psm_quick(f, subsong);
    } else if (signature_size >= 4 && signature[0] == 'P' &&
               signature[1] == 'S' && signature[2] == 'M' &&
               signature[3] == 254) {
        duh = dumb_read_old_psm_quick(f);
    } else if (signature_size >= 3 && signature[0] == 'M' &&
               signature[1] == 'T' && signature[2] == 'M') {
        duh = dumb_read_mtm_quick(f);
    } else if (signature_size >= 4 && signature[0] == 'R' &&
               signature[1] == 'I' && signature[2] == 'F' &&
               signature[3] == 'F') {
        duh = dumb_read_riff_quick(f);
    } else if (signature_size >= 24 &&
               !memcmp(signature, "ASYLUM Music Format", 19) &&
               !memcmp(signature + 19, " V1.0", 5)) {
        duh = dumb_read_asy_quick(f);
    } else if (signature_size >= 3 && signature[0] == 'A' &&
               signature[1] == 'M' && signature[2] == 'F') {
        duh = dumb_read_amf_quick(f);
    } else if (signature_size >= 8 && !memcmp(signature, "OKTASONG", 8)) {
        duh = dumb_read_okt_quick(f);
    }

    if (!duh) {
        dumbfile_seek(f, 0, DFS_SEEK_SET);
        duh = dumb_read_mod_quick(f, restrict_);
    }

    return duh;
}
示例#15
0
文件: reads3m.c 项目: eukos16/NGUNIX
static int it_s3m_read_pattern(IT_PATTERN *pattern, DUMBFILE *f, unsigned char *buffer)
{
	int buflen = 0;
	int bufpos = 0;

	IT_ENTRY *entry;

	unsigned char channel;

	/* Haha, this is hilarious!
	 *
	 * Well, after some experimentation, it seems that different S3M writers
	 * define the format in different ways. The S3M docs say that the first
	 * two bytes hold the "length of [the] packed pattern", and the packed
	 * pattern data follow. Judging by the contents of ARMANI.S3M, packaged
	 * with ScreamTracker itself, the measure of length _includes_ the two
	 * bytes used to store the length; in other words, we should read
	 * (length - 2) more bytes. However, aryx.s3m, packaged with ModPlug
	 * Tracker, excludes these two bytes, so (length) more bytes must be
	 * read.
	 *
	 * Call me crazy, but I just find it insanely funny that the format was
	 * misunderstood in this way :D
	 *
	 * Now we can't just risk reading two extra bytes, because then we
	 * overshoot, and DUMBFILEs don't support backward seeking (for a good
	 * reason). Luckily, there is a way. We can read the data little by
	 * little, and stop when we have 64 rows in memory. Provided we protect
	 * against buffer overflow, this method should work with all sensibly
	 * written S3M files. If you find one for which it does not work, please
	 * let me know at [email protected] so I can look at it.
	 */

	/* Discard the length. */
	dumbfile_skip(f, 2);

	if (dumbfile_error(f))
		return -1;

	pattern->n_rows = 0;
	pattern->n_entries = 0;

	/* Read in the pattern data, little by little, and work out how many
	 * entries we need room for. Sorry, but this is just so funny...
	 */
	for (;;) {
		unsigned char b = buffer[buflen++] = dumbfile_getc(f);

#if 1
		static const unsigned char used[8] = {0, 2, 1, 3, 2, 4, 3, 5};
		channel = b & 31;
		b >>= 5;
		pattern->n_entries++;
		if (b) {
			if (buflen + used[b] >= 65536) return -1;
			dumbfile_getnc(buffer + buflen, used[b], f);
			buflen += used[b];
		} else {
			/* End of row */
			if (++pattern->n_rows == 64) break;
			if (buflen >= 65536) return -1;
		}
#else
		if (b == 0) {
			/* End of row */
			pattern->n_entries++;
			if (++pattern->n_rows == 64) break;
			if (buflen >= 65536) return -1;
		} else {
			static const unsigned char used[8] = {0, 2, 1, 3, 2, 4, 3, 5};
			channel = b & 31;
			b >>= 5;
			if (b) {
				pattern->n_entries++;
				if (buflen + used[b] >= 65536) return -1;
				dumbfile_getnc(buffer + buflen, used[b], f);
				buflen += used[b];
			}
		}
#endif

		/* We have ensured that buflen < 65536 at this point, so it is safe
		 * to iterate and read at least one more byte without checking.
		 * However, now would be a good time to check for errors reading from
		 * the file.
		 */

		if (dumbfile_error(f))
			return -1;
	}

	pattern->entry = malloc(pattern->n_entries * sizeof(*pattern->entry));

	if (!pattern->entry)
		return -1;

	entry = pattern->entry;

	while (bufpos < buflen) {
		unsigned char b = buffer[bufpos++];

#if 1
		if (!(b & ~31))
#else
		if (b == 0)
#endif
		{
			/* End of row */
			IT_SET_END_ROW(entry);
			entry++;
			continue;
		}

		channel = b & 31;

		if (b & 224) {
			entry->mask = 0;
			entry->channel = channel;

			if (b & 32) {
				unsigned char n = buffer[bufpos++];
				if (n != 255) {
					if (n == 254)
						entry->note = IT_NOTE_CUT;
					else
						entry->note = (n >> 4) * 12 + (n & 15);
					entry->mask |= IT_ENTRY_NOTE;
				}

				entry->instrument = buffer[bufpos++];
				if (entry->instrument)
					entry->mask |= IT_ENTRY_INSTRUMENT;
			}

			if (b & 64) {
				entry->volpan = buffer[bufpos++];
				if (entry->volpan != 255)
					entry->mask |= IT_ENTRY_VOLPAN;
			}

			if (b & 128) {
				entry->effect = buffer[bufpos++];
				entry->effectvalue = buffer[bufpos++];
				if (entry->effect != 255) {
					entry->mask |= IT_ENTRY_EFFECT;
					if (entry->effect == IT_BREAK_TO_ROW)
						entry->effectvalue -= (entry->effectvalue >> 4) * 6;
				}
示例#16
0
static int it_xm_read_instrument(IT_INSTRUMENT *instrument, XM_INSTRUMENT_EXTRA *extra, DUMBFILE *f)
{
	unsigned long size, bytes_read;
	unsigned short vol_points[24];
	unsigned short pan_points[24];
	int i, type;
	const unsigned long max_size = 4 + 22 + 1 + 2 + 4 + 96 + 48 + 48 + 1 * 14 + 2 + 2;
	unsigned long skip_end = 0;

	/* Header size. Tends to be more than the actual size of the structure.
	 * So unread bytes must be skipped before reading the first sample
	 * header.
	 */

	if ( limit_xm_resize( f, 4 ) < 0 ) return -1;

	size = dumbfile_igetl(f);

	if ( size == 0 ) size = max_size;
	else if ( size > max_size )
	{
		skip_end = size - max_size;
		size = max_size;
	}

	if ( limit_xm_resize( f, size - 4 ) < 0 ) return -1;

    dumbfile_getnc((char *)instrument->name, 22, f);
	instrument->name[22] = 0;
    trim_whitespace((char *)instrument->name, 22);
	instrument->filename[0] = 0;
	dumbfile_skip(f, 1);  /* Instrument type. Should be 0, but seems random. */
	extra->n_samples = dumbfile_igetw(f);

	if (dumbfile_error(f) || (unsigned int)extra->n_samples > XM_MAX_SAMPLES_PER_INSTRUMENT)
		return -1;

	bytes_read = 4 + 22 + 1 + 2;

	if (extra->n_samples) {
		/* sample header size */
		/*i = dumbfile_igetl(f);
		if (!i || i > 0x28) i = 0x28;*/
		dumbfile_skip(f, 4);
		i = 0x28;
		extra->sample_header_size = i;

		/* sample map */
		for (i = 0; i < 96; i++) {
			instrument->map_sample[i] = dumbfile_getc(f) + 1;
			instrument->map_note[i] = i;
		}

		if (dumbfile_error(f))
			return 1;

		/* volume/panning envelopes */
		for (i = 0; i < 24; i++)
			vol_points[i] = dumbfile_igetw(f);
		for (i = 0; i < 24; i++)
			pan_points[i] = dumbfile_igetw(f);

		instrument->volume_envelope.n_nodes = dumbfile_getc(f);
		instrument->pan_envelope.n_nodes = dumbfile_getc(f);

		if (dumbfile_error(f))
			return -1;

		instrument->volume_envelope.sus_loop_start = dumbfile_getc(f);
		instrument->volume_envelope.loop_start = dumbfile_getc(f);
		instrument->volume_envelope.loop_end = dumbfile_getc(f);

		instrument->pan_envelope.sus_loop_start = dumbfile_getc(f);
		instrument->pan_envelope.loop_start = dumbfile_getc(f);
		instrument->pan_envelope.loop_end = dumbfile_getc(f);

		/* The envelope handler for XM files won't use sus_loop_end. */

		type = dumbfile_getc(f);
		instrument->volume_envelope.flags = 0;
		if ((type & XM_ENVELOPE_ON) && instrument->volume_envelope.n_nodes)
			instrument->volume_envelope.flags |= IT_ENVELOPE_ON;
		if (type & XM_ENVELOPE_LOOP)    instrument->volume_envelope.flags |= IT_ENVELOPE_LOOP_ON;
#if 1
		if (type & XM_ENVELOPE_SUSTAIN) instrument->volume_envelope.flags |= IT_ENVELOPE_SUSTAIN_LOOP;
#else // This is now handled in itrender.c
		/* let's avoid fading out when reaching the last envelope node */
		if (!(type & XM_ENVELOPE_LOOP)) {
			instrument->volume_envelope.loop_start = instrument->volume_envelope.n_nodes-1;
			instrument->volume_envelope.loop_end = instrument->volume_envelope.n_nodes-1;
		}
		instrument->volume_envelope.flags |= IT_ENVELOPE_LOOP_ON;
#endif

		type = dumbfile_getc(f);
		instrument->pan_envelope.flags = 0;
		if ((type & XM_ENVELOPE_ON) && instrument->pan_envelope.n_nodes)
			instrument->pan_envelope.flags |= IT_ENVELOPE_ON;
		if (type & XM_ENVELOPE_LOOP)    instrument->pan_envelope.flags |= IT_ENVELOPE_LOOP_ON; // should this be here?
		if (type & XM_ENVELOPE_SUSTAIN) instrument->pan_envelope.flags |= IT_ENVELOPE_SUSTAIN_LOOP;

		if (it_xm_make_envelope(&instrument->volume_envelope, vol_points, 0) != 0) {
			TRACE("XM error: volume envelope\n");
			if (instrument->volume_envelope.flags & IT_ENVELOPE_ON) return -1;
		}

		if (it_xm_make_envelope(&instrument->pan_envelope, pan_points, -32) != 0) {
			TRACE("XM error: pan envelope\n");
			if (instrument->pan_envelope.flags & IT_ENVELOPE_ON) return -1;
		}

		instrument->pitch_envelope.flags = 0;

		extra->vibrato_type = dumbfile_getc(f);
		extra->vibrato_sweep = dumbfile_getc(f);
		extra->vibrato_depth = dumbfile_getc(f);
		extra->vibrato_speed = dumbfile_getc(f);

		if (dumbfile_error(f) || extra->vibrato_type > 4) // XXX
			return -1;

		/** WARNING: lossy approximation */
		instrument->fadeout = (dumbfile_igetw(f)*128 + 64)/0xFFF;

		dumbfile_skip(f, 2); /* reserved */

		bytes_read += 4 + 96 + 48 + 48 + 14*1 + 2 + 2;
	} else
		for (i = 0; i < 96; i++)
			instrument->map_sample[i] = 0;

	if (size > bytes_read && dumbfile_skip(f, size - bytes_read))
		return -1;

	if (skip_end && limit_xm_skip_end(f, skip_end))
		return -1;

	instrument->new_note_action = NNA_NOTE_CUT;
	instrument->dup_check_type = DCT_OFF;
	instrument->dup_check_action = DCA_NOTE_CUT;
	instrument->pp_separation = 0;
	instrument->pp_centre = 60; /* C-5 */
	instrument->global_volume = 128;
	instrument->default_pan = 32;
	instrument->random_volume = 0;
	instrument->random_pan = 0;
	instrument->filter_cutoff = 0;
	instrument->filter_resonance = 0;

	return 0;
}
示例#17
0
static int it_xm_read_pattern(IT_PATTERN *pattern, DUMBFILE *f, int n_channels, unsigned char *buffer, int version)
{
	int size;
	int pos;
	int channel;
	int row;
	int effect, effectvalue;
	IT_ENTRY *entry;

	/* pattern header size */
	if (dumbfile_igetl(f) != ( version == 0x0102 ? 0x08 : 0x09 ) ) {
		TRACE("XM error: unexpected pattern header size\n");
		return -1;
	}

	/* pattern data packing type */
	if (dumbfile_getc(f) != 0) {
		TRACE("XM error: unexpected pattern packing type\n");
		return -1;
	}

	if ( version == 0x0102 )
		pattern->n_rows = dumbfile_getc(f) + 1;
	else
		pattern->n_rows = dumbfile_igetw(f);  /* 1..256 */
	size = dumbfile_igetw(f);
	pattern->n_entries = 0;

	if (dumbfile_error(f))
		return -1;

	if (size == 0)
		return 0;

	if (size > 1280 * n_channels) {
		TRACE("XM error: pattern data size > %d bytes\n", 1280 * n_channels);
		return -1;
	}

    if (dumbfile_getnc((char *)buffer, size, f) < size)
		return -1;

	/* compute number of entries */
	pattern->n_entries = 0;
	pos = channel = row = 0;
	while (pos < size) {
		if (!(buffer[pos] & XM_ENTRY_PACKED) || (buffer[pos] & 31))
			pattern->n_entries++;

		channel++;
		if (channel >= n_channels) {
			channel = 0;
			row++;
			pattern->n_entries++;
		}

		if (buffer[pos] & XM_ENTRY_PACKED) {
			static const char offset[] = { 0, 1, 1, 2, 1, 2, 2, 3,   1, 2, 2, 3, 2, 3, 3, 4,
			                               1, 2, 2, 3, 2, 3, 3, 4,   2, 3, 3, 4, 3, 4, 4, 5 };
			pos += 1 + offset[buffer[pos] & 31];
		} else {
			pos += 5;
		}
	}

	if (row > pattern->n_rows) {
		TRACE("XM error: wrong number of rows in pattern data\n");
		return -1;
	}

	/* Whoops, looks like some modules may be short, a few channels, maybe even rows... */

	while (row < pattern->n_rows)
	{
		pattern->n_entries++;
		row++;
	}

	pattern->entry = malloc(pattern->n_entries * sizeof(*pattern->entry));
	if (!pattern->entry)
		return -1;

	/* read the entries */
	entry = pattern->entry;
	pos = channel = row = 0;
	while (pos < size) {
		unsigned char mask;

		if (buffer[pos] & XM_ENTRY_PACKED)
			mask = buffer[pos++] & 31;
		else
			mask = 31;

		if (mask) {
			ASSERT(entry < pattern->entry + pattern->n_entries);

			entry->channel = channel;
			entry->mask = 0;

			if (mask & XM_ENTRY_NOTE) {
				int note = buffer[pos++]; /* 1-96 <=> C0-B7 */
				entry->note = (note == XM_NOTE_OFF) ? (IT_NOTE_OFF) : (note-1);
				entry->mask |= IT_ENTRY_NOTE;
			}

			if (mask & XM_ENTRY_INSTRUMENT) {
				entry->instrument = buffer[pos++]; /* 1-128 */
				entry->mask |= IT_ENTRY_INSTRUMENT;
			}

			if (mask & XM_ENTRY_VOLUME)
				it_xm_convert_volume(buffer[pos++], entry);

			effect = effectvalue = 0;
			if (mask & XM_ENTRY_EFFECT)      effect = buffer[pos++];
			if (mask & XM_ENTRY_EFFECTVALUE) effectvalue = buffer[pos++];
			_dumb_it_xm_convert_effect(effect, effectvalue, entry, 0);

			entry++;
		}

		channel++;
		if (channel >= n_channels) {
			channel = 0;
			row++;
			IT_SET_END_ROW(entry);
			entry++;
		}
	}

	while (row < pattern->n_rows)
	{
		row++;
		IT_SET_END_ROW(entry);
		entry++;
	}

	return 0;
}
示例#18
0
static int it_riff_dsmf_process_sample( IT_SAMPLE * sample, DUMBFILE * f, int len )
{
    int flags;

    dumbfile_getnc( (char *) sample->filename, 13, f );
    sample->filename[ 14 ] = 0;

    flags = dumbfile_igetw( f );
    sample->default_volume = dumbfile_getc( f );
    sample->length = dumbfile_igetl( f );
    sample->loop_start = dumbfile_igetl( f );
    sample->loop_end = dumbfile_igetl( f );
    dumbfile_skip( f, 32 - 28 );
    sample->C5_speed = dumbfile_igetw( f ) * 2;
    dumbfile_skip( f, 36 - 34 );
    dumbfile_getnc( (char *) sample->name, 28, f );
    sample->name[ 28 ] = 0;

    /*if ( data[ 0x38 ] || data[ 0x39 ] || data[ 0x3A ] || data[ 0x3B ] )
    	return -1;*/

    if ( ! sample->length ) {
        sample->flags &= ~IT_SAMPLE_EXISTS;
        return 0;
    }

    /*if ( flags & ~( 2 | 1 ) )
    	return -1;*/

    if ( sample->length + 64 > len )
        return -1;

    sample->flags = IT_SAMPLE_EXISTS;

    sample->default_pan = 0;
    sample->global_volume = 64;
    sample->vibrato_speed = 0;
    sample->vibrato_depth = 0;
    sample->vibrato_rate = 0;
    sample->vibrato_waveform = IT_VIBRATO_SINE;
    sample->finetune = 0;
    sample->max_resampling_quality = -1;

    if ( flags & 1 )
    {
        if (((unsigned int)sample->loop_end <= (unsigned int)sample->length) &&
                ((unsigned int)sample->loop_start < (unsigned int)sample->loop_end))
        {
            sample->length = sample->loop_end;
            sample->flags |= IT_SAMPLE_LOOP;
            if ( flags & 0x10 ) sample->flags |= IT_SAMPLE_PINGPONG_LOOP;
        }
    }

    sample->data = malloc( sample->length );
    if ( ! sample->data )
        return -1;

    dumbfile_getnc( sample->data, sample->length, f );

    if ( ! ( flags & 2 ) )
    {
        for ( flags = 0; flags < sample->length; ++flags )
            ( ( signed char * ) sample->data ) [ flags ] ^= 0x80;
    }

    return 0;
}
示例#19
0
static DUMB_IT_SIGDATA *it_riff_dsmf_load_sigdata( DUMBFILE * f, struct riff * stream )
{
    DUMB_IT_SIGDATA *sigdata;

    int n, o, found;

    if ( ! stream ) goto error;

    if ( stream->type != DUMB_ID( 'D', 'S', 'M', 'F' ) ) goto error;

    sigdata = malloc(sizeof(*sigdata));
    if ( ! sigdata ) goto error;

    sigdata->n_patterns = 0;
    sigdata->n_samples = 0;
    sigdata->name[0] = 0;

    found = 0;

    for ( n = 0; (unsigned)n < stream->chunk_count; ++n )
    {
        struct riff_chunk * c = stream->chunks + n;
        switch( c->type )
        {
        case DUMB_ID( 'S' ,'O' ,'N' ,'G' ):
            /* initialization data */
            if ( ( found ) || ( c->size < 192 ) ) goto error_sd;
            found = 1;
            break;

        case DUMB_ID( 'P', 'A', 'T', 'T' ):
            ++ sigdata->n_patterns;
            break;

        case DUMB_ID( 'I', 'N', 'S', 'T' ):
            ++ sigdata->n_samples;
            break;
        }
    }

    if ( !found || !sigdata->n_samples || !sigdata->n_patterns ) goto error_sd;

    if ( sigdata->n_samples > 255 || sigdata->n_patterns > 255 ) goto error_sd;

    sigdata->song_message = NULL;
    sigdata->order = NULL;
    sigdata->instrument = NULL;
    sigdata->sample = NULL;
    sigdata->pattern = NULL;
    sigdata->midi = NULL;
    sigdata->checkpoint = NULL;

    sigdata->mixing_volume = 48;
    sigdata->pan_separation = 128;

    sigdata->n_instruments = 0;
    sigdata->n_orders = 0;
    sigdata->restart_position = 0;

    memset(sigdata->channel_volume, 64, DUMB_IT_N_CHANNELS);

    for (n = 0; n < DUMB_IT_N_CHANNELS; n += 4) {
        int sep = 32 * dumb_it_default_panning_separation / 100;
        sigdata->channel_pan[n  ] = 32 - sep;
        sigdata->channel_pan[n+1] = 32 + sep;
        sigdata->channel_pan[n+2] = 32 + sep;
        sigdata->channel_pan[n+3] = 32 - sep;
    }

    for ( n = 0; (unsigned)n < stream->chunk_count; ++n )
    {
        struct riff_chunk * c = stream->chunks + n;
        switch ( c->type )
        {
        case DUMB_ID( 'S', 'O', 'N', 'G' ):
            if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
            dumbfile_getnc( (char *) sigdata->name, 28, f );
            sigdata->name[ 28 ] = 0;
            sigdata->flags = IT_STEREO | IT_OLD_EFFECTS | IT_COMPATIBLE_GXX;
            dumbfile_skip( f, 36 - 28 );
            sigdata->n_orders = dumbfile_igetw( f );
            //sigdata->n_samples = ptr[ 38 ] | ( ptr[ 39 ] << 8 ); // whatever
            //sigdata->n_patterns = ptr[ 40 ] | ( ptr[ 41 ] << 8 );
            dumbfile_skip( f, 42 - 38 );
            sigdata->n_pchannels = dumbfile_igetw( f );
            sigdata->global_volume = dumbfile_getc( f );
            sigdata->mixing_volume = dumbfile_getc( f );
            sigdata->speed = dumbfile_getc( f );
            sigdata->tempo = dumbfile_getc( f );

            for ( o = 0; o < 16; ++o )
            {
                sigdata->channel_pan[ o ] = dumbfile_getc( f ) / 2;
            }

            sigdata->order = malloc( 128 );
            if ( ! sigdata->order ) goto error_usd;
            dumbfile_getnc( (char *) sigdata->order, 128, f );

            break;
        }
    }

    sigdata->pattern = malloc( sigdata->n_patterns * sizeof( *sigdata->pattern ) );
    if ( ! sigdata->pattern ) goto error_usd;
    for ( n = 0; n < sigdata->n_patterns; ++n )
        sigdata->pattern[ n ].entry = NULL;

    sigdata->sample = malloc( sigdata->n_samples * sizeof( *sigdata->sample ) );
    if ( ! sigdata->sample ) goto error_usd;
    for ( n = 0; n < sigdata->n_samples; ++n )
    {
        IT_SAMPLE * sample = sigdata->sample + n;
        sample->data = NULL;
    }

    sigdata->n_samples = 0;
    sigdata->n_patterns = 0;

    for ( n = 0; (unsigned)n < stream->chunk_count; ++n )
    {
        struct riff_chunk * c = stream->chunks + n;
        switch ( c->type )
        {
        case DUMB_ID( 'P', 'A', 'T', 'T' ):
            if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
            if ( it_riff_dsmf_process_pattern( sigdata->pattern + sigdata->n_patterns, f, c->size ) ) goto error_usd;
            ++ sigdata->n_patterns;
            break;

        case DUMB_ID( 'I', 'N', 'S', 'T' ):
            if ( dumbfile_seek( f, c->offset, DFS_SEEK_SET ) ) goto error_usd;
            if ( it_riff_dsmf_process_sample( sigdata->sample + sigdata->n_samples, f, c->size ) ) goto error_usd;
            ++ sigdata->n_samples;
            break;
        }
    }

    _dumb_it_fix_invalid_orders( sigdata );

    return sigdata;

error_usd:
    _dumb_it_unload_sigdata( sigdata );
    goto error;
error_sd:
    free( sigdata );
error:
    return NULL;
}
示例#20
0
文件: reads3m.c 项目: codefoco/dumb
static int it_s3m_read_sample_header(IT_SAMPLE *sample, long *offset,
                                     unsigned char *pack, int cwtv,
                                     DUMBFILE *f) {
    unsigned char type;
    int flags;

    type = dumbfile_getc(f);

    dumbfile_getnc((char *)sample->filename, 12, f);
    sample->filename[12] = 0;

    if (type > 1) {
        /** WARNING: no adlib support */
        dumbfile_skip(f, 3 + 12 + 1 + 1 + 2 + 2 + 2 + 12);
        dumbfile_getnc((char *)sample->name, 28, f);
        sample->name[28] = 0;
        dumbfile_skip(f, 4);
        sample->flags &= ~IT_SAMPLE_EXISTS;
        return dumbfile_error(f);
    }

    *offset = dumbfile_getc(f) << 20;
    *offset += dumbfile_igetw(f) << 4;

    sample->length = dumbfile_igetl(f);
    sample->loop_start = dumbfile_igetl(f);
    sample->loop_end = dumbfile_igetl(f);

    sample->default_volume = dumbfile_getc(f);

    dumbfile_skip(f, 1);

    flags = dumbfile_getc(f);

    if (flags < 0 || (flags != 0 && flags != 4))
        /* Sample is packed apparently (or error reading from file). We don't
         * know how to read packed samples.
         */
        return -1;

    *pack = flags;

    flags = dumbfile_getc(f);

    sample->C5_speed = dumbfile_igetl(f) << 1;

    /* Skip four unused bytes and three internal variables. */
    dumbfile_skip(f, 4 + 2 + 2 + 4);

    dumbfile_getnc((char *)sample->name, 28, f);
    sample->name[28] = 0;

    if (type == 0 || sample->length <= 0) {
        /* Looks like no-existy. Anyway, there's for sure no 'SCRS' ... */
        sample->flags &= ~IT_SAMPLE_EXISTS;
        return dumbfile_error(f);
    }

    if (dumbfile_mgetl(f) != DUMB_ID('S', 'C', 'R', 'S'))
        return -1;

    sample->global_volume = 64;

    sample->flags = IT_SAMPLE_EXISTS;
    if (flags & 1)
        sample->flags |= IT_SAMPLE_LOOP;

    /* The ST3 TECH.DOC is unclear on this, but IMAGO Orpheus is not. Piece of
     * crap. */

    if (flags & 2) {
        sample->flags |= IT_SAMPLE_STEREO;

        if ((cwtv & 0xF000) == 0x2000) {
            sample->length >>= 1;
            sample->loop_start >>= 1;
            sample->loop_end >>= 1;
        }
示例#21
0
文件: reads3m.c 项目: eukos16/NGUNIX
static int it_s3m_read_sample_header(IT_SAMPLE *sample, long *offset, DUMBFILE *f)
{
	unsigned char type;
	int flags;

	type = dumbfile_getc(f);

	if (type > 1) {
		/** WARNING: no adlib support */
	}

	dumbfile_getnc(sample->filename, 13, f);
	sample->filename[13] = 0;

	*offset = dumbfile_igetw(f) << 4;

	sample->length = dumbfile_igetl(f);
	sample->loop_start = dumbfile_igetl(f);
	sample->loop_end = dumbfile_igetl(f);

	sample->default_volume = dumbfile_getc(f);

	dumbfile_skip(f, 1);

	if (dumbfile_getc(f) != 0)
		/* Sample is packed apparently (or error reading from file). We don't
		 * know how to read packed samples.
		 */
		return -1;

	flags = dumbfile_getc(f);

	sample->C5_speed = dumbfile_igetl(f) << 1;

	/* Skip four unused bytes and three internal variables. */
	dumbfile_skip(f, 4+2+2+4);

	dumbfile_getnc(sample->name, 28, f);
	sample->name[28] = 0;

	if (type == 0) {
		/* Looks like no-existy. Anyway, there's for sure no 'SCRS' ... */
		sample->flags &= ~IT_SAMPLE_EXISTS;
		return dumbfile_error(f);
	}

	if (dumbfile_mgetl(f) != DUMB_ID('S','C','R','S'))
		return -1;

	sample->global_volume = 64;

	sample->flags = IT_SAMPLE_EXISTS;
	if (flags & 1) sample->flags |= IT_SAMPLE_LOOP;
	if (flags & 2) sample->flags |= IT_SAMPLE_STEREO;
	if (flags & 4) sample->flags |= IT_SAMPLE_16BIT;

	sample->default_pan = 0; // 0 = don't use, or 160 = centre?

	if (sample->length <= 0)
		sample->flags &= ~IT_SAMPLE_EXISTS;
	else if (sample->flags & IT_SAMPLE_LOOP) {
		if ((unsigned int)sample->loop_end > (unsigned int)sample->length)
			sample->flags &= ~IT_SAMPLE_LOOP;
		else if ((unsigned int)sample->loop_start >= (unsigned int)sample->loop_end)
			sample->flags &= ~IT_SAMPLE_LOOP;
		else
			/* ScreamTracker seems not to save what comes after the loop end
			 * point, but rather to assume it is a duplicate of what comes at
			 * the loop start point. I am not completely sure of this though.
			 * It is easy to evade; simply truncate the sample.
			 */
			sample->length = sample->loop_end;
	}


	//Do we need to set all these?
	sample->vibrato_speed = 0;
	sample->vibrato_depth = 0;
	sample->vibrato_rate = 0;
	sample->vibrato_waveform = IT_VIBRATO_SINE;

	return dumbfile_error(f);
}
示例#22
0
文件: readasy.c 项目: codefoco/dumb
static DUMB_IT_SIGDATA *it_asy_load_sigdata(DUMBFILE *f) {
    DUMB_IT_SIGDATA *sigdata;
    int i;

    static const char sig_part[] = "ASYLUM Music Format";
    static const char sig_rest[] =
        " V1.0"; /* whee, string space optimization with format type below */

    char signature[32];

    if (dumbfile_getnc(signature, 32, f) != 32 ||
        memcmp(signature, sig_part, 19) ||
        memcmp(signature + 19, sig_rest, 5)) {
        return NULL;
    }

    sigdata = malloc(sizeof(*sigdata));
    if (!sigdata) {
        return NULL;
    }

    sigdata->speed = dumbfile_getc(f); /* XXX seems to fit the files I have */
    sigdata->tempo = dumbfile_getc(f); /* ditto */
    sigdata->n_samples = dumbfile_getc(f); /* ditto */
    sigdata->n_patterns = dumbfile_getc(f);
    sigdata->n_orders = dumbfile_getc(f);
    sigdata->restart_position = dumbfile_getc(f);

    if (dumbfile_error(f) || !sigdata->n_samples || sigdata->n_samples > 64 ||
        !sigdata->n_patterns || !sigdata->n_orders) {
        free(sigdata);
        return NULL;
    }

    if (sigdata->restart_position > sigdata->n_orders) /* XXX */
        sigdata->restart_position = 0;

    sigdata->order = malloc(sigdata->n_orders);
    if (!sigdata->order) {
        free(sigdata);
        return NULL;
    }

    if (dumbfile_getnc((char *)sigdata->order, sigdata->n_orders, f) !=
            sigdata->n_orders ||
        dumbfile_skip(f, 256 - sigdata->n_orders)) {
        free(sigdata->order);
        free(sigdata);
        return NULL;
    }

    sigdata->sample = malloc(sigdata->n_samples * sizeof(*sigdata->sample));
    if (!sigdata->sample) {
        free(sigdata->order);
        free(sigdata);
        return NULL;
    }

    sigdata->song_message = NULL;
    sigdata->instrument = NULL;
    sigdata->pattern = NULL;
    sigdata->midi = NULL;
    sigdata->checkpoint = NULL;

    sigdata->n_instruments = 0;

    for (i = 0; i < sigdata->n_samples; ++i)
        sigdata->sample[i].data = NULL;

    for (i = 0; i < sigdata->n_samples; ++i) {
        if (it_asy_read_sample_header(&sigdata->sample[i], f)) {
            _dumb_it_unload_sigdata(sigdata);
            return NULL;
        }
    }

    if (dumbfile_skip(f, 37 * (64 - sigdata->n_samples))) {
        _dumb_it_unload_sigdata(sigdata);
        return NULL;
    }

    sigdata->pattern = malloc(sigdata->n_patterns * sizeof(*sigdata->pattern));
    if (!sigdata->pattern) {
        _dumb_it_unload_sigdata(sigdata);
        return NULL;
    }
    for (i = 0; i < sigdata->n_patterns; ++i)
        sigdata->pattern[i].entry = NULL;

    /* Read in the patterns */
    {
        unsigned char *buffer =
            malloc(64 * 8 * 4); /* 64 rows * 8 channels * 4 bytes */
        if (!buffer) {
            _dumb_it_unload_sigdata(sigdata);
            return NULL;
        }
        for (i = 0; i < sigdata->n_patterns; ++i) {
            if (it_asy_read_pattern(&sigdata->pattern[i], f, buffer) != 0) {
                free(buffer);
                _dumb_it_unload_sigdata(sigdata);
                return NULL;
            }
        }
        free(buffer);
    }

    /* And finally, the sample data */
    for (i = 0; i < sigdata->n_samples; ++i) {
        if (it_asy_read_sample_data(&sigdata->sample[i], f)) {
            _dumb_it_unload_sigdata(sigdata);
            return NULL;
        }
    }

    /* Now let's initialise the remaining variables, and we're done! */
    sigdata->flags = IT_WAS_AN_XM | IT_WAS_A_MOD | IT_OLD_EFFECTS |
                     IT_COMPATIBLE_GXX | IT_STEREO;

    sigdata->global_volume = 128;
    sigdata->mixing_volume = 48;
    sigdata->pan_separation = 128;

    sigdata->n_pchannels = 8;

    sigdata->name[0] = 0;

    memset(sigdata->channel_volume, 64, DUMB_IT_N_CHANNELS);

    for (i = 0; i < DUMB_IT_N_CHANNELS; i += 4) {
        int sep = 32 * dumb_it_default_panning_separation / 100;
        sigdata->channel_pan[i + 0] = 32 - sep;
        sigdata->channel_pan[i + 1] = 32 + sep;
        sigdata->channel_pan[i + 2] = 32 + sep;
        sigdata->channel_pan[i + 3] = 32 - sep;
    }

    if (_dumb_it_fix_invalid_orders(sigdata) < 0) {
        _dumb_it_unload_sigdata(sigdata);
        return NULL;
    }

    return sigdata;
}