예제 #1
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;
}
예제 #2
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;
}
예제 #3
0
파일: readdsmf.c 프로젝트: spikeh/deadbeef
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;
}
예제 #4
0
파일: readdsmf.c 프로젝트: AkumaKing/Xeu
static int it_riff_dsmf_process_pattern( IT_PATTERN * pattern, const unsigned char * data, int len )
{
	int length, row, pos;
	unsigned flags;
	IT_ENTRY * entry;

	length = data[ 0 ] | ( data[ 1 ] << 8 );
	if ( length > len ) return -1;

	data += 2;
	len = length - 2;

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

	row = 0;
	pos = 0;

	while ( (row < 64) && (pos < len) ) {
		if ( ! data[ pos ] ) {
			++ row;
			++ pos;
			continue;
		}

		flags = data[ pos++ ] & 0xF0;

		if (flags) {
			++ pattern->n_entries;
			if (flags & 0x80) pos ++;
			if (flags & 0x40) pos ++;
			if (flags & 0x20) pos ++;
			if (flags & 0x10) pos += 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;
	pos = 0;

	while ( ( row < 64 ) && ( pos < len ) )
	{
		if ( ! data[ pos ] )
		{
			IT_SET_END_ROW( entry );
			++ entry;
			++ row;
			++ pos;
			continue;
		}

		flags = data[ pos++ ];
		entry->channel = flags & 0x0F;
		entry->mask = 0;

		if ( flags & 0xF0 )
		{
			if ( flags & 0x80 )
			{
				if ( data[ pos ] )
				{
					entry->mask |= IT_ENTRY_NOTE;
					entry->note = data[ pos ] - 1;
				}
				++ pos;
			}

			if ( flags & 0x40 )
			{
				if ( data[ pos ] )
				{
					entry->mask |= IT_ENTRY_INSTRUMENT;
					entry->instrument = data[ pos ];
				}
				++ pos;
			}

			if ( flags & 0x20 )
			{
				entry->mask |= IT_ENTRY_VOLPAN;
				entry->volpan = data[ pos ];
				++ pos;
			}

			if ( flags & 0x10 )
			{
				_dumb_it_xm_convert_effect( data[ pos ], data[ pos + 1 ], entry, 0 );
				pos += 2;
			}

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

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

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

	return 0;
}