Exemplo n.º 1
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
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;
}