예제 #1
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;
    long size;

    size = dumbfile_get_size(f);

    stream = riff_parse( f, 0, size, 1 );
    if ( ! stream ) stream = riff_parse( f, 0, size, 0 );

	if ( ! stream ) return 0;

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

	riff_free( stream );

	return duh;
}
예제 #2
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;
}
예제 #3
0
파일: riff.c 프로젝트: 1Akula1/gzdoom
void riff_free( struct riff * stream )
{
	if ( stream )
	{
		if ( stream->chunks )
		{
			unsigned i;
			for ( i = 0; i < stream->chunk_count; ++i )
			{
				struct riff_chunk * chunk = stream->chunks + i;
				if ( chunk->type == DUMB_ID('R','I','F','F') ) riff_free( ( struct riff * ) chunk->data );
				else free( chunk->data );
			}
			free( stream->chunks );
		}
		free( stream );
	}
}
예제 #4
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;
}
예제 #5
0
파일: readdsmf.c 프로젝트: spikeh/deadbeef
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;
}
예제 #6
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;
        }
예제 #7
0
파일: riff.c 프로젝트: kode54/Cog
struct riff *riff_parse(DUMBFILE *f, long offset, long size, unsigned proper) {
    unsigned stream_size;
    struct riff *stream;

    if (size < 8)
        return 0;

    if (dumbfile_seek(f, offset, DFS_SEEK_SET))
        return 0;
    if (dumbfile_mgetl(f) != DUMB_ID('R', 'I', 'F', 'F'))
        return 0;

    stream_size = (int)dumbfile_igetl(f);
    if (stream_size + 8 > size)
        return 0;
    if (stream_size < 4)
        return 0;

    stream = (struct riff *)malloc(sizeof(struct riff));
    if (!stream)
        return 0;

    stream->type = (int)dumbfile_mgetl(f);
    stream->chunk_count = 0;
    stream->chunks = 0;

    stream_size -= 4;

    while (stream_size && !dumbfile_error(f)) {
        struct riff_chunk *chunk;
        if (stream_size < 8)
            break;
        stream->chunks = (struct riff_chunk *)realloc(
            stream->chunks,
            (stream->chunk_count + 1) * sizeof(struct riff_chunk));
        if (!stream->chunks)
            break;
        chunk = stream->chunks + stream->chunk_count;
        chunk->type = (int)dumbfile_mgetl(f);
        chunk->size = (int)dumbfile_igetl(f);
        chunk->offset = dumbfile_pos(f);
        stream_size -= 8;
        if (stream_size < chunk->size)
            break;
        if (chunk->type == DUMB_ID('R', 'I', 'F', 'F')) {
            chunk->nested =
                riff_parse(f, chunk->offset - 8, chunk->size + 8, proper);
            if (!chunk->nested)
                break;
        } else {
            chunk->nested = 0;
        }
        dumbfile_seek(f, chunk->offset + chunk->size, DFS_SEEK_SET);
        stream_size -= chunk->size;
        if (proper && (chunk->size & 1)) {
            dumbfile_skip(f, 1);
            --stream_size;
        }
        ++stream->chunk_count;
    }

    if (stream_size) {
        riff_free(stream);
        stream = 0;
    }

    return stream;
}
예제 #8
0
파일: readdsmf.c 프로젝트: AkumaKing/Xeu
static DUMB_IT_SIGDATA *it_riff_dsmf_load_sigdata( struct riff * stream )
{
	DUMB_IT_SIGDATA *sigdata;

	int n, o, found;

	unsigned char * ptr;

	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 int)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) {
		sigdata->channel_pan[n  ] = 16;
		sigdata->channel_pan[n+1] = 48;
		sigdata->channel_pan[n+2] = 48;
		sigdata->channel_pan[n+3] = 16;
	}

	for ( n = 0; (unsigned int)n < stream->chunk_count; ++n )
	{
		struct riff_chunk * c = stream->chunks + n;
		switch ( c->type )
		{
		case DUMB_ID( 'S', 'O', 'N', 'G' ):
			ptr = ( unsigned char * ) c->data;
			memcpy( sigdata->name, c->data, 28 );
			sigdata->name[ 28 ] = 0;
			sigdata->flags = IT_WAS_AN_XM | IT_WAS_A_MOD | IT_STEREO | IT_OLD_EFFECTS | IT_COMPATIBLE_GXX;
			sigdata->n_orders = ptr[ 36 ] | ( ptr[ 37 ] << 8 );
			//sigdata->n_samples = ptr[ 38 ] | ( ptr[ 39 ] << 8 ); // whatever
			//sigdata->n_patterns = ptr[ 40 ] | ( ptr[ 41 ] << 8 );
			sigdata->n_pchannels = ptr[ 42 ] | ( ptr[ 43 ] << 8 );
			sigdata->global_volume = ptr[ 44 ];
			sigdata->mixing_volume = ptr[ 45 ];
			sigdata->speed = ptr[ 46 ];
			sigdata->tempo = ptr[ 47 ];

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

			sigdata->order = malloc( 128 );
			if ( ! sigdata->order ) goto error_usd;
			memcpy( sigdata->order, ptr + 64, 128 );

			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 int)n < stream->chunk_count; ++n )
	{
		struct riff_chunk * c = stream->chunks + n;
		switch ( c->type )
		{
		case DUMB_ID( 'P', 'A', 'T', 'T' ):
			if ( it_riff_dsmf_process_pattern( sigdata->pattern + sigdata->n_patterns, ( unsigned char * ) c->data, c->size ) ) goto error_usd;
			++ sigdata->n_patterns;
			break;

		case DUMB_ID( 'I', 'N', 'S', 'T' ):
			if ( it_riff_dsmf_process_sample( sigdata->sample + sigdata->n_samples, ( unsigned char * ) c->data, 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;
}
예제 #9
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);
}
예제 #10
0
파일: riff.c 프로젝트: 1Akula1/gzdoom
struct riff * riff_parse( unsigned char * ptr, unsigned size, unsigned proper )
{
	unsigned stream_size;
	struct riff * stream;

	if ( size < 8 ) return 0;

	if ( ptr[0] != 'R' || ptr[1] != 'I' || ptr[2] != 'F' || ptr[3] != 'F' ) return 0;

	stream_size = ptr[4] | ( ptr[5] << 8 ) | ( ptr[6] << 16 ) | ( ptr[7] << 24 );
	if ( stream_size + 8 > size ) return 0;
	if ( stream_size < 4 ) return 0;

	stream = malloc( sizeof( struct riff ) );
	if ( ! stream ) return 0;

	stream->type = ( ptr[8] << 24 ) | ( ptr[9] << 16 ) | ( ptr[10] << 8 ) | ptr[11];
	stream->chunk_count = 0;
	stream->chunks = 0;

	ptr += 12;
	stream_size -= 4;

	while ( stream_size )
	{
		struct riff_chunk * chunk;
		if ( stream_size < 8 ) break;
		stream->chunks = realloc( stream->chunks, ( stream->chunk_count + 1 ) * sizeof( struct riff_chunk ) );
		if ( ! stream->chunks ) break;
		chunk = stream->chunks + stream->chunk_count;
		chunk->type = ( ptr[0] << 24 ) | ( ptr[1] << 16 ) | ( ptr[2] << 8 ) | ptr[3];
		chunk->size = ptr[4] | ( ptr[5] << 8 ) | ( ptr[6] << 16 ) | ( ptr[7] << 24 );
		ptr += 8;
		stream_size -= 8;
		if ( stream_size < chunk->size ) break;
		if ( chunk->type == DUMB_ID('R','I','F','F') )
		{
			chunk->data = riff_parse( ptr - 8, chunk->size + 8, proper );
			if ( ! chunk->data ) break;
		}
		else
		{
			chunk->data = malloc( chunk->size );
			if ( ! chunk->data ) break;
			memcpy( chunk->data, ptr, chunk->size );
		}
		ptr += chunk->size;
		stream_size -= chunk->size;
		if ( proper && ( chunk->size & 1 ) )
		{
			++ ptr;
			-- stream_size;
		}
		++stream->chunk_count;
	}
	
	if ( stream_size )
	{
		riff_free( stream );
		stream = 0;
	}

	return stream;
}