Пример #1
0
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;
}
Пример #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
static int it_s3m_read_sample_data(IT_SAMPLE *sample, int ffi, DUMBFILE *f)
{
	long n;

	long datasize = sample->length;
	if (sample->flags & IT_SAMPLE_STEREO) datasize <<= 1;

	sample->data = malloc(datasize * (sample->flags & IT_SAMPLE_16BIT ? 2 : 1));
	if (!sample->data)
		return -1;

	if (sample->flags & IT_SAMPLE_STEREO) {
		if (sample->flags & IT_SAMPLE_16BIT) {
			for (n = 0; n < datasize; n += 2)
				((short *)sample->data)[n] = dumbfile_igetw(f);
			for (n = 1; n < datasize; n += 2)
				((short *)sample->data)[n] = dumbfile_igetw(f);
		} else {
			for (n = 0; n < datasize; n += 2)
				((signed char *)sample->data)[n] = dumbfile_getc(f);
			for (n = 1; n < datasize; n += 2)
				((signed char *)sample->data)[n] = dumbfile_getc(f);
		}
	} else if (sample->flags & IT_SAMPLE_16BIT)
		for (n = 0; n < sample->length; n++)
			((short *)sample->data)[n] = dumbfile_igetw(f);
	else
		for (n = 0; n < sample->length; n++)
			((signed char *)sample->data)[n] = dumbfile_getc(f);

	if (dumbfile_error(f))
		return -1;

	if (ffi != 1) {
		/* Convert to signed. */
		if (sample->flags & IT_SAMPLE_16BIT)
			for (n = 0; n < datasize; n++)
				((short *)sample->data)[n] ^= 0x8000;
		else
			for (n = 0; n < datasize; n++)
				((signed char *)sample->data)[n] ^= 0x80;
	}

	return 0;
}
Пример #4
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;
	}
Пример #5
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;
}
Пример #6
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;
}
Пример #7
0
static int it_riff_dsmf_process_pattern( IT_PATTERN * pattern, DUMBFILE * f, int len )
{
    int length, row;
    unsigned flags;
    long start, end;
    int p, q, r;
    IT_ENTRY * entry;

    length = dumbfile_igetw( f );
    if ( length > len ) return -1;

    len = length - 2;

    pattern->n_rows = 64;
    pattern->n_entries = 64;

    row = 0;

    start = dumbfile_pos( f );
    end = start + len;

    while ( (row < 64) && !dumbfile_error( f ) && (dumbfile_pos( f ) < end) ) {
        p = dumbfile_getc( f );
        if ( ! p ) {
            ++ row;
            continue;
        }

        flags = p & 0xF0;

        if (flags) {
            ++ pattern->n_entries;
            if (flags & 0x80) dumbfile_skip( f, 1 );
            if (flags & 0x40) dumbfile_skip( f, 1 );
            if (flags & 0x20) dumbfile_skip( f, 1 );
            if (flags & 0x10) dumbfile_skip( f, 2 );
        }
    }

    if ( pattern->n_entries == 64 ) return 0;

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

    entry = pattern->entry;

    row = 0;

    if ( dumbfile_seek( f, start, DFS_SEEK_SET ) ) return -1;

    while ( ( row < 64 ) && !dumbfile_error( f ) && ( dumbfile_pos( f ) < end ) )
    {
        p = dumbfile_getc( f );
        if ( ! p )
        {
            IT_SET_END_ROW( entry );
            ++ entry;
            ++ row;
            continue;
        }

        flags = p;
        entry->channel = flags & 0x0F;
        entry->mask = 0;

        if ( flags & 0xF0 )
        {
            if ( flags & 0x80 )
            {
                q = dumbfile_getc( f );
                if ( q )
                {
                    entry->mask |= IT_ENTRY_NOTE;
                    entry->note = q - 1;
                }
            }

            if ( flags & 0x40 )
            {
                q = dumbfile_getc( f );
                if ( q )
                {
                    entry->mask |= IT_ENTRY_INSTRUMENT;
                    entry->instrument = q;
                }
            }

            if ( flags & 0x20 )
            {
                entry->mask |= IT_ENTRY_VOLPAN;
                entry->volpan = dumbfile_getc( f );
            }

            if ( flags & 0x10 )
            {
                q = dumbfile_getc( f );
                r = dumbfile_getc( f );
                _dumb_it_xm_convert_effect( q, r, entry, 0 );
            }

            if (entry->mask) entry++;
        }
    }

    while ( row < 64 )
    {
        IT_SET_END_ROW( entry );
        ++ entry;
        ++ row;
    }

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

    return 0;
}
Пример #8
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;
}
Пример #9
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;
}
Пример #10
0
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;
        }
Пример #11
0
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);
}
Пример #12
0
static sigdata_t *sample_load_sigdata(DUH *duh, DUMBFILE *file)
{
	SAMPLE_SIGDATA *sigdata;
	long size;
	long n;
	int flags;

	(void)duh;

	size = dumbfile_igetl(file);

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

	flags = dumbfile_getc(file);
	if (flags < 0)
		return NULL;

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

	sigdata->samples = malloc(size * sizeof(sample_t));
	if (!sigdata->samples) {
		free(sigdata);
		return NULL;
	}

	sigdata->size = size;
	sigdata->flags = flags;

	if (sigdata->flags & (SAMPFLAG_LOOP | SAMPFLAG_XLOOP)) {
		sigdata->loop_start = dumbfile_igetl(file);

		if (dumbfile_error(file) || (unsigned long)sigdata->loop_start >= (unsigned long)size) {
			free(sigdata->samples);
			free(sigdata);
			return NULL;
		}

		if (sigdata->flags & SAMPFLAG_LOOP)
			sigdata->loop_end = size;
		else {
			sigdata->loop_end = dumbfile_igetl(file);

			if (dumbfile_error(file) || sigdata->loop_end <= sigdata->loop_start || sigdata->loop_end > size) {
				free(sigdata->samples);
				free(sigdata);
				return NULL;
			}
		}
	} else {
		sigdata->loop_start = 0;
		sigdata->loop_end = size;
	}

	if (sigdata->flags & SAMPFLAG_16BIT) {
		for (n = 0; n < size; n++) {
			int m = dumbfile_igetw(file);
			if (m < 0) {
				free(sigdata->samples);
				free(sigdata);
				return NULL;
			}
			sigdata->samples[n] = (int)(signed short)m << 8;
		}
	} else {
		for (n = 0; n < size; n++) {
			int m = dumbfile_getc(file);
			if (m < 0) {
				free(sigdata->samples);
				free(sigdata);
				return NULL;
			}
			sigdata->samples[n] = (int)(signed char)m << 16;
		}
	}

	return sigdata;
}