Exemplo n.º 1
0
static int read_wav_sample(mame_file *f, struct loaded_sample *sample)
{
	unsigned long offset = 0;
	UINT32 length, rate, filesize;
	UINT16 bits, temp16;
	char buf[32];
	#ifndef LSB_FIRST
	UINT32 sindex;
	#endif

	/* read the core header and make sure it's a WAVE file */
	offset += mame_fread(f, buf, 4);
	if (offset < 4)
		return 0;
	if (memcmp(&buf[0], "RIFF", 4) != 0)
		return 0;

	/* get the total size */
	offset += mame_fread(f, &filesize, 4);
	if (offset < 8)
		return 0;
	filesize = intelLong(filesize);

	/* read the RIFF file type and make sure it's a WAVE file */
	offset += mame_fread(f, buf, 4);
	if (offset < 12)
		return 0;
	if (memcmp(&buf[0], "WAVE", 4) != 0)
		return 0;

	/* seek until we find a format tag */
	while (1)
	{
		offset += mame_fread(f, buf, 4);
		offset += mame_fread(f, &length, 4);
		length = intelLong(length);
		if (memcmp(&buf[0], "fmt ", 4) == 0)
			break;

		/* seek to the next block */
		mame_fseek(f, length, SEEK_CUR);
		offset += length;
		if (offset >= filesize)
			return 0;
	}

	/* read the format -- make sure it is PCM */
	offset += mame_fread(f, &temp16, 2);
	temp16 = LITTLE_ENDIANIZE_INT16(temp16);
	if (temp16 != 1)
		return 0;

	/* number of channels -- only mono is supported */
	offset += mame_fread(f, &temp16, 2);
	temp16 = LITTLE_ENDIANIZE_INT16(temp16);
	if (temp16 != 1)
		return 0;

	/* sample rate */
	offset += mame_fread(f, &rate, 4);
	rate = intelLong(rate);

	/* bytes/second and block alignment are ignored */
	offset += mame_fread(f, buf, 6);

	/* bits/sample */
	offset += mame_fread(f, &bits, 2);
	bits = LITTLE_ENDIANIZE_INT16(bits);
	if (bits != 8 && bits != 16)
		return 0;

	/* seek past any extra data */
	mame_fseek(f, length - 16, SEEK_CUR);
	offset += length - 16;

	/* seek until we find a data tag */
	while (1)
	{
		offset += mame_fread(f, buf, 4);
		offset += mame_fread(f, &length, 4);
		length = intelLong(length);
		if (memcmp(&buf[0], "data", 4) == 0)
			break;

		/* seek to the next block */
		mame_fseek(f, length, SEEK_CUR);
		offset += length;
		if (offset >= filesize)
			return 0;
	}

	/* if there was a 0 length data block, we're done */
	if (length == 0)
		return 0;

	/* fill in the sample data */
	sample->length = length;
	sample->frequency = rate;

	/* read the data in */
	if (bits == 8)
	{
		unsigned char *tempptr;
		int sindex;

		sample->data = auto_malloc(sizeof(*sample->data) * length);
		mame_fread(f, sample->data, length);

		/* convert 8-bit data to signed samples */
		tempptr = (unsigned char *)sample->data;
		for (sindex = length - 1; sindex >= 0; sindex--)
			sample->data[sindex] = (INT8)(tempptr[sindex] ^ 0x80) * 256;
	}
	else
	{
		/* 16-bit data is fine as-is */
		sample->data = auto_malloc(sizeof(*sample->data) * (length/2));
		mame_fread(f, sample->data, length);
		sample->length /= 2;
#ifndef LSB_FIRST
		for (sindex = 0; sindex < sample->length; sindex++)
			sample->data[sindex] = LITTLE_ENDIANIZE_INT16(sample->data[sindex]);
#endif
	}
	return 1;
}
Exemplo n.º 2
0
static int wave_write(int id)
{
	struct wave_file *w = &wave[id];
	UINT32 filesize, offset = 0, temp32;
	UINT16 temp16;

	if( !w->file )
        return WAVE_ERR;

    while( w->playpos < w->samples )
    {
		*((INT16 *)w->data + w->playpos) = 0;
		w->playpos++;
	}

    filesize =
		4 + 	/* 'RIFF' */
		4 + 	/* size of entire file */
		8 + 	/* 'WAVEfmt ' */
		20 +	/* WAVE tag  (including size -- 0x10 in dword) */
		4 + 	/* 'data' */
		4 + 	/* size of data */
		w->length;

    /* write the core header for a WAVE file */
	offset += osd_fwrite(w->file, "RIFF", 4);
    if( offset < 4 )
    {
		logerror("WAVE write error at offs %d\n", offset);
		return WAVE_ERR;
    }

	temp32 = intelLong(filesize) - 8;
	offset += osd_fwrite(w->file, &temp32, 4);

	/* read the RIFF file type and make sure it's a WAVE file */
	offset += osd_fwrite(w->file, "WAVE", 4);
	if( offset < 12 )
	{
		logerror("WAVE write error at offs %d\n", offset);
		return WAVE_ERR;
	}

	/* write a format tag */
	offset += osd_fwrite(w->file, "fmt ", 4);
    if( offset < 12 )
	{
		logerror("WAVE write error at offs %d\n", offset);
		return WAVE_ERR;
    }
    /* size of the following 'fmt ' fields */
    offset += osd_fwrite(w->file, "\x10\x00\x00\x00", 4);
	if( offset < 16 )
	{
		logerror("WAVE write error at offs %d\n", offset);
		return WAVE_ERR;
    }

	/* format: PCM */
	temp16 = 1;
	offset += osd_fwrite_lsbfirst(w->file, &temp16, 2);
	if( offset < 18 )
	{
		logerror("WAVE write error at offs %d\n", offset);
		return WAVE_ERR;
    }

	/* channels: 1 (mono) */
	temp16 = 1;
    offset += osd_fwrite_lsbfirst(w->file, &temp16, 2);
	if( offset < 20 )
	{
		logerror("WAVE write error at offs %d\n", offset);
		return WAVE_ERR;
    }

	/* sample rate */
	temp32 = intelLong(w->smpfreq);
	offset += osd_fwrite(w->file, &temp32, 4);
	if( offset < 24 )
	{
		logerror("WAVE write error at offs %d\n", offset);
		return WAVE_ERR;
    }

	/* byte rate */
	temp32 = intelLong(w->smpfreq * w->resolution / 8);
	offset += osd_fwrite(w->file, &temp32, 4);
	if( offset < 28 )
	{
		logerror("WAVE write error at offs %d\n", offset);
		return WAVE_ERR;
    }

	/* block align (size of one `sample') */
	temp16 = w->resolution / 8;
	offset += osd_fwrite_lsbfirst(w->file, &temp16, 2);
	if( offset < 30 )
	{
		logerror("WAVE write error at offs %d\n", offset);
		return WAVE_ERR;
    }

	/* block align */
	temp16 = w->resolution;
	offset += osd_fwrite_lsbfirst(w->file, &temp16, 2);
	if( offset < 32 )
	{
		logerror("WAVE write error at offs %d\n", offset);
		return WAVE_ERR;
    }

	/* 'data' tag */
	offset += osd_fwrite(w->file, "data", 4);
	if( offset < 36 )
	{
		logerror("WAVE write error at offs %d\n", offset);
		return WAVE_ERR;
    }

	/* data size */
	temp32 = intelLong(w->length);
	offset += osd_fwrite(w->file, &temp32, 4);
	if( offset < 40 )
	{
		logerror("WAVE write error at offs %d\n", offset);
		return WAVE_ERR;
    }

	if( osd_fwrite_lsbfirst(w->file, w->data, w->length) != w->length )
	{
		logerror("WAVE write error at offs %d\n", offset);
		return WAVE_ERR;
    }

	return WAVE_OK;
}
Exemplo n.º 3
0
/*****************************************************************************
 * helper functions
 *****************************************************************************/
static int wave_read(int id)
{
	struct wave_file *w = &wave[id];
    UINT32 offset = 0;
	UINT32 filesize, temp32;
	UINT16 channels, bits, temp16;
	char buf[32];

	if( !w->file )
		return WAVE_ERR;

    /* read the core header and make sure it's a WAVE file */
	offset += osd_fread(w->file, buf, 4);
	if( offset < 4 )
	{
		logerror("WAVE read error at offs %d\n", offset);
		return WAVE_ERR;
	}
	if( memcmp (&buf[0], "RIFF", 4) != 0 )
	{
		logerror("WAVE header not 'RIFF'\n");
		return WAVE_FMT;
    }

	/* get the total size */
	offset += osd_fread(w->file, &temp32, 4);
	if( offset < 8 )
	{
		logerror("WAVE read error at offs %d\n", offset);
		return WAVE_ERR;
	}
	filesize = intelLong(temp32);
	logerror("WAVE filesize %u bytes\n", filesize);

	/* read the RIFF file type and make sure it's a WAVE file */
	offset += osd_fread(w->file, buf, 4);
	if( offset < 12 )
	{
		logerror("WAVE read error at offs %d\n", offset);
		return WAVE_ERR;
	}
	if( memcmp (&buf[0], "WAVE", 4) != 0 )
	{
		logerror("WAVE RIFF type not 'WAVE'\n");
		return WAVE_FMT;
	}

	/* seek until we find a format tag */
	while( 1 )
	{
		offset += osd_fread(w->file, buf, 4);
		offset += osd_fread(w->file, &temp32, 4);
		w->length = intelLong(temp32);
		if( memcmp(&buf[0], "fmt ", 4) == 0 )
			break;

		/* seek to the next block */
		osd_fseek(w->file, w->length, SEEK_CUR);
		offset += w->length;
		if( offset >= filesize )
		{
			logerror("WAVE no 'fmt ' tag found\n");
			return WAVE_ERR;
        }
	}

	/* read the format -- make sure it is PCM */
	offset += osd_fread_lsbfirst(w->file, &temp16, 2);
	if( temp16 != 1 )
	{
		logerror("WAVE format %d not supported (not = 1 PCM)\n", temp16);
			return WAVE_ERR;
    }
	logerror("WAVE format %d (PCM)\n", temp16);

	/* number of channels -- only mono is supported */
	offset += osd_fread_lsbfirst(w->file, &channels, 2);
	if( channels != 1 && channels != 2 )
	{
		logerror("WAVE channels %d not supported (only 1 mono or 2 stereo)\n", channels);
		return WAVE_ERR;
    }
	logerror("WAVE channels %d\n", channels);

	/* sample rate */
	offset += osd_fread(w->file, &temp32, 4);
	w->smpfreq = intelLong(temp32);
	logerror("WAVE sample rate %d Hz\n", w->smpfreq);

	/* bytes/second and block alignment are ignored */
	offset += osd_fread(w->file, buf, 6);

	/* bits/sample */
	offset += osd_fread_lsbfirst(w->file, &bits, 2);
	if( bits != 8 && bits != 16 )
	{
		logerror("WAVE %d bits/sample not supported (only 8/16)\n", bits);
		return WAVE_ERR;
    }
	logerror("WAVE bits/sample %d\n", bits);
	w->resolution = bits;

	/* seek past any extra data */
	osd_fseek(w->file, w->length - 16, SEEK_CUR);
	offset += w->length - 16;

	/* seek until we find a data tag */
	while( 1 )
	{
		offset += osd_fread(w->file, buf, 4);
		offset += osd_fread(w->file, &temp32, 4);
		w->length = intelLong(temp32);
		if( memcmp(&buf[0], "data", 4) == 0 )
			break;

		/* seek to the next block */
		osd_fseek(w->file, w->length, SEEK_CUR);
		offset += w->length;
		if( offset >= filesize )
		{
			logerror("WAVE not 'data' tag found\n");
			return WAVE_ERR;
        }
	}

	/* allocate the game sample */
	w->data = malloc(w->length);

	if( w->data == NULL )
	{
		logerror("WAVE failed to malloc %d bytes\n", w->length);
		return WAVE_ERR;
    }

	/* read the data in */
	if( w->resolution == 8 )
	{
		if( osd_fread(w->file, w->data, w->length) != w->length )
		{
			logerror("WAVE failed read %d data bytes\n", w->length);
			free(w->data);
			return WAVE_ERR;
		}
		if( channels == 2 )
		{
			UINT8 *src = w->data;
			INT8 *dst = w->data;
			logerror("WAVE mixing 8-bit unsigned stereo to 8-bit signed mono\n");
            /* convert stereo 8-bit data to mono signed samples */
			for( temp32 = 0; temp32 < w->length/2; temp32++ )
			{
				*dst = ((src[0] + src[1]) / 2) ^ 0x80;
				dst += 1;
				src += 2;
			}
			w->length /= 2;
            w->data = realloc(w->data, w->length);
			if( w->data == NULL )
			{
				logerror("WAVE failed to malloc %d bytes\n", w->length);
				return WAVE_ERR;
			}
        }
		else
		{
			UINT8 *src = w->data;
			INT8 *dst = w->data;
            logerror("WAVE converting 8-bit unsigned to 8-bit signed\n");
            /* convert 8-bit data to signed samples */
			for( temp32 = 0; temp32 < w->length; temp32++ )
				*dst++ = *src++ ^ 0x80;
		}
	}
	else
	{
		/* 16-bit data is fine as-is */
		if( osd_fread_lsbfirst(w->file, w->data, w->length) != w->length )
		{
			logerror("WAVE failed read %d data bytes\n", w->length);
			free(w->data);
			return WAVE_ERR;
        }
        if( channels == 2 )
        {
			INT16 *src = w->data;
			INT16 *dst = w->data;
            logerror("WAVE mixing 16-bit stereo to 16-bit mono\n");
            /* convert stereo 16-bit data to mono */
			for( temp32 = 0; temp32 < w->length/2; temp32++ )
			{
				*dst = ((INT32)src[0] + (INT32)src[1]) / 2;
				dst += 1;
				src += 2;
			}
			w->length /= 2;
			w->data = realloc(w->data, w->length);
			if( w->data == NULL )
			{
				logerror("WAVE failed to malloc %d bytes\n", w->length);
				return WAVE_ERR;
            }
        }
		else
		{
			logerror("WAVE using 16-bit signed samples as is\n");
        }
	}
	w->samples = w->length * 8 / w->resolution;
	logerror("WAVE %d samples - %d:%02d\n", w->samples, (w->samples/w->smpfreq)/60, (w->samples/w->smpfreq)%60);

	return WAVE_OK;
}
Exemplo n.º 4
0
static struct GameSample *read_wav_sample(void *f)
{
	unsigned long offset = 0;
	UINT32 length, rate, filesize, temp32;
	UINT16 bits, temp16;
	char buf[32];
	struct GameSample *result;

	/* read the core header and make sure it's a WAVE file */
	offset += osd_fread(f, buf, 4);
	if (offset < 4)
		return NULL;
	if (memcmp(&buf[0], "RIFF", 4) != 0)
		return NULL;

	/* get the total size */
	offset += osd_fread(f, &filesize, 4);
	if (offset < 8)
		return NULL;
	filesize = intelLong(filesize);

	/* read the RIFF file type and make sure it's a WAVE file */
	offset += osd_fread(f, buf, 4);
	if (offset < 12)
		return NULL;
	if (memcmp(&buf[0], "WAVE", 4) != 0)
		return NULL;

	/* seek until we find a format tag */
	while (1)
	{
		offset += osd_fread(f, buf, 4);
		offset += osd_fread(f, &length, 4);
		length = intelLong(length);
		if (memcmp(&buf[0], "fmt ", 4) == 0)
			break;

		/* seek to the next block */
		osd_fseek(f, length, SEEK_CUR);
		offset += length;
		if (offset >= filesize)
			return NULL;
	}

	/* read the format -- make sure it is PCM */
	offset += osd_fread_lsbfirst(f, &temp16, 2);
	if (temp16 != 1)
		return NULL;

	/* number of channels -- only mono is supported */
	offset += osd_fread_lsbfirst(f, &temp16, 2);
	if (temp16 != 1)
		return NULL;

	/* sample rate */
	offset += osd_fread(f, &rate, 4);
	rate = intelLong(rate);

	/* bytes/second and block alignment are ignored */
	offset += osd_fread(f, buf, 6);

	/* bits/sample */
	offset += osd_fread_lsbfirst(f, &bits, 2);
	if (bits != 8 && bits != 16)
		return NULL;

	/* seek past any extra data */
	osd_fseek(f, length - 16, SEEK_CUR);
	offset += length - 16;

	/* seek until we find a data tag */
	while (1)
	{
		offset += osd_fread(f, buf, 4);
		offset += osd_fread(f, &length, 4);
		length = intelLong(length);
		if (memcmp(&buf[0], "data", 4) == 0)
			break;

		/* seek to the next block */
		osd_fseek(f, length, SEEK_CUR);
		offset += length;
		if (offset >= filesize)
			return NULL;
	}

	/* allocate the game sample */
	result = malloc(sizeof(struct GameSample) + length);
	if (result == NULL)
		return NULL;

	/* fill in the sample data */
	result->length = length;
	result->smpfreq = rate;
	result->resolution = bits;

	/* read the data in */
	if (bits == 8)
	{
		osd_fread(f, result->data, length);

		/* convert 8-bit data to signed samples */
		for (temp32 = 0; temp32 < length; temp32++)
			result->data[temp32] ^= 0x80;
	}
	else
	{
		/* 16-bit data is fine as-is */
		osd_fread_lsbfirst(f, result->data, length);
	}

	return result;
}