예제 #1
0
파일: wavfile.c 프로젝트: Fulg/mame
static casserr_t wavfile_process(cassette_image *cassette, struct CassetteOptions *opts,
	int read_waveform)
{
	UINT8 file_header[12];
	UINT8 tag_header[8];
	UINT8 format_tag[16];
	UINT32 stated_size;
	UINT64 file_size;
	UINT32 tag_size;
	UINT32 tag_samples;
	UINT64 offset;
	int format_specified = FALSE;

	UINT16 format_type = 0;
	UINT32 bytes_per_second = 0;
//  UINT16 block_align = 0;
	int waveform_flags = 0;

	/* read header */
	cassette_image_read(cassette, file_header, 0, sizeof(file_header));
	offset = sizeof(file_header);

	/* check magic numbers */
	if (memcmp(&file_header[0], magic1, 4))
		return CASSETTE_ERROR_INVALIDIMAGE;
	if (memcmp(&file_header[8], magic2, 4))
		return CASSETTE_ERROR_INVALIDIMAGE;

	/* read and sanity check size */
	stated_size = get_leuint32(&file_header[4]) + 8;
	file_size = cassette_image_size(cassette);
	if (stated_size > file_size)
		stated_size = (UINT32) file_size;

	while(offset < stated_size)
	{
		cassette_image_read(cassette, tag_header, offset, sizeof(tag_header));
		tag_size = get_leuint32(&tag_header[4]);
		offset += sizeof(tag_header);

		if (!memcmp(tag_header, format_tag_id, 4))
		{
			/* format tag */
			if (format_specified || (tag_size < sizeof(format_tag)))
				return CASSETTE_ERROR_INVALIDIMAGE;
			format_specified = TRUE;

			cassette_image_read(cassette, format_tag, offset, sizeof(format_tag));

			format_type             = get_leuint16(&format_tag[0]);
			opts->channels          = get_leuint16(&format_tag[2]);
			opts->sample_frequency  = get_leuint32(&format_tag[4]);
			bytes_per_second        = get_leuint32(&format_tag[8]);
//          block_align             = get_leuint16(&format_tag[12]);
			opts->bits_per_sample   = get_leuint16(&format_tag[14]);

			if (format_type != WAV_FORMAT_PCM)
				return CASSETTE_ERROR_INVALIDIMAGE;
			if (opts->sample_frequency * opts->bits_per_sample * opts->channels / 8 != bytes_per_second)
				return CASSETTE_ERROR_INVALIDIMAGE;

			switch(opts->bits_per_sample)
			{
				case 8:
					waveform_flags = CASSETTE_WAVEFORM_8BIT | CASSETTE_WAVEFORM_UNSIGNED;   // 8-bits wav are stored unsigned
					break;
				case 16:
					waveform_flags = CASSETTE_WAVEFORM_16BITLE;
					break;
				case 32:
					waveform_flags = CASSETTE_WAVEFORM_32BITLE;
					break;
				default:
					return CASSETTE_ERROR_INVALIDIMAGE;
			}
		}
		else if (!memcmp(tag_header, data_tag_id, 4))
		{
			/* data tag */
			if (!format_specified)
				return CASSETTE_ERROR_INVALIDIMAGE;

			if (read_waveform)
			{
				tag_samples = tag_size / (opts->bits_per_sample / 8) / opts->channels;
				cassette_read_samples(cassette, opts->channels, 0.0, tag_samples / ((double) opts->sample_frequency),
					tag_samples, offset, waveform_flags);
			}
		}
		else
		{
			/* ignore other tags */
		}
		offset += tag_size;
	}

	return CASSETTE_ERROR_SUCCESS;
}
예제 #2
0
파일: csw_cas.cpp 프로젝트: Robbbert/store1
static int csw_cas_to_wav_size( const uint8_t *casdata, int caslen )
{
	uint32_t SampleRate;
	uint32_t NumberOfPulses;
	uint8_t  MajorRevision;
	uint8_t  MinorRevision;
	uint8_t  CompressionType;
	uint8_t  Flags;
	uint8_t  HeaderExtensionLength;
	std::vector<uint8_t> gz_ptr;

	int         total_size;
	z_stream    d_stream;
	int         err;
	uint8_t       *in_ptr;
	int         bsize=0;

	if ( memcmp( casdata, CSW_HEADER, sizeof(CSW_HEADER)-1 ) )
	{
		LOG_FORMATS( "csw_cas_to_wav_size: cassette image has incompatible header\n" );
		goto cleanup;
	}

	if (casdata[0x16]!=0x1a)
	{
		LOG_FORMATS( "csw_cas_to_wav_size: Terminator Code Not Found\n" );
		goto cleanup;
	}

	MajorRevision=casdata[0x17];
	MinorRevision=casdata[0x18];

	LOG_FORMATS("Version %d : %d\n",MajorRevision,MinorRevision);

	if (casdata[0x17]!=2)
	{
		LOG_FORMATS( "csw_cas_to_wav_size: Unsuported Major Version\n" );
		goto cleanup;
	}

	SampleRate=get_leuint32(casdata+0x19);
	LOG_FORMATS("Sample rate %u\n",SampleRate);

	NumberOfPulses=get_leuint32(casdata+0x1d);
	LOG_FORMATS("Number Of Pulses %u\n",NumberOfPulses);


	CompressionType=casdata[0x21];
	Flags=casdata[0x22];
	HeaderExtensionLength=casdata[0x23];

	LOG_FORMATS("CompressionType %u   Flast %u   HeaderExtensionLength %u\n",CompressionType,Flags,HeaderExtensionLength);

	mycaslen=caslen;
	//from here on down for now I am assuming it is compressed csw file.
	in_ptr = (uint8_t*) casdata+0x34+HeaderExtensionLength;

	gz_ptr.resize( 8 );

	d_stream.next_in = (unsigned char *)in_ptr;
	d_stream.avail_in = caslen - ( in_ptr - casdata );
	d_stream.total_in=0;

	d_stream.next_out = &gz_ptr[0];
	d_stream.avail_out = 1;
	d_stream.total_out=0;

	d_stream.zalloc = nullptr;
	d_stream.zfree = nullptr;
	d_stream.opaque = nullptr;
	d_stream.data_type=0;

	err = inflateInit( &d_stream );
	if ( err != Z_OK )
	{
		LOG_FORMATS( "inflateInit2 error: %d\n", err );
		goto cleanup;
	}


	total_size=1;
	do
	{
		d_stream.next_out = &gz_ptr[0];
		d_stream.avail_out=1;
		err=inflate( &d_stream, Z_SYNC_FLUSH );
		if (err==Z_OK)
		{
			bsize=gz_ptr[0];
			if (bsize==0)
			{
				d_stream.avail_out=4;
				d_stream.next_out = &gz_ptr[0];
				err=inflate( &d_stream, Z_SYNC_FLUSH );
				bsize=get_leuint32(&gz_ptr[0]);
			}
			total_size=total_size+bsize;
		}
	}
	while (err==Z_OK);

	if ( err != Z_STREAM_END )
	{
		LOG_FORMATS( "inflate error: %d\n", err );
		goto cleanup;
	}

	err = inflateEnd( &d_stream );
	if ( err != Z_OK )
	{
		LOG_FORMATS( "inflateEnd error: %d\n", err );
		goto cleanup;
	}

	return total_size;

cleanup:
	return -1;
}
예제 #3
0
static int csw_cas_fill_wave( INT16 *buffer, int length, UINT8 *bytes ) {
UINT32 SampleRate;
UINT32 NumberOfPulses;
UINT8  CompressionType;
UINT8  Flags;
UINT8  HeaderExtensionLength;
INT8   Bit;

UINT8 *gz_ptr = NULL;
int			total_size;
z_stream	d_stream;
int 		err;
UINT8		*in_ptr;
int 		bsize=0;
int		i;


	LOG_FORMATS("Length %d\n",length);

	SampleRate=get_leuint32(bytes+0x19);
	LOG_FORMATS("Sample rate %d\n",SampleRate);

	NumberOfPulses=get_leuint32(bytes+0x1d);
	LOG_FORMATS("Number Of Pulses %d\n",NumberOfPulses);

	CompressionType=bytes[0x21];
	Flags=bytes[0x22];
	HeaderExtensionLength=bytes[0x23];

	if ((Flags&0)==0)
	{
		Bit=-100;
	} else {
		Bit=100;
	}

	LOG_FORMATS("CompressionType %d   Flast %d   HeaderExtensionLength %d\n",CompressionType,Flags,HeaderExtensionLength);


	//from here on down for now I am assuming it is compressed csw file.
	in_ptr = (UINT8*) bytes+0x34+HeaderExtensionLength;

	gz_ptr = (UINT8*)malloc( 8 );


	d_stream.next_in = (unsigned char *)in_ptr;
	d_stream.avail_in = mycaslen - ( in_ptr - bytes );
	d_stream.total_in=0;

	d_stream.next_out = gz_ptr;
	d_stream.avail_out = 1;
	d_stream.total_out=0;

	d_stream.zalloc = 0;
	d_stream.zfree = 0;
	d_stream.opaque = 0;
	d_stream.data_type=0;

	err = inflateInit( &d_stream );
	if ( err != Z_OK ) {
		LOG_FORMATS( "inflateInit2 error: %d\n", err );
		goto cleanup;
	}

	total_size=0;

	do
	{
		d_stream.next_out = gz_ptr;
		d_stream.avail_out=1;
		err=inflate( &d_stream, Z_SYNC_FLUSH );
		if (err==Z_OK) {
			bsize=gz_ptr[0];
			if (bsize==0) {
				d_stream.avail_out=4;
				d_stream.next_out = gz_ptr;
				err=inflate( &d_stream, Z_SYNC_FLUSH );
				bsize=get_leuint32(gz_ptr);
			}
			for (i=0;i<bsize;i++)
			{
				buffer[total_size++]=Bit;
			}
			Bit=-Bit;
		}
	}
	while (err==Z_OK);

	if ( err != Z_STREAM_END ) {
		LOG_FORMATS( "inflate error: %d\n", err );
		goto cleanup;
	}

	err = inflateEnd( &d_stream );
	if ( err != Z_OK ) {
		LOG_FORMATS( "inflateEnd error: %d\n", err );
		goto cleanup;
	}






	if ( gz_ptr ) {
		free( gz_ptr );
		gz_ptr = NULL;
	}




	return length;



	cleanup:
		if ( gz_ptr ) {
			free( gz_ptr );
			gz_ptr = NULL;
		}
	return -1;
}
예제 #4
0
파일: csw_cas.cpp 프로젝트: Robbbert/store1
static int csw_cas_fill_wave( int16_t *buffer, int length, uint8_t *bytes )
{
	uint32_t SampleRate;
	uint32_t NumberOfPulses;
	uint8_t  CompressionType;
	uint8_t  Flags;
	uint8_t  HeaderExtensionLength;
	int8_t   Bit;

	std::vector<uint8_t> gz_ptr;
	int         total_size;
	z_stream    d_stream;
	int         err;
	uint8_t       *in_ptr;
	int         bsize=0;
	int     i;


	LOG_FORMATS("Length %d\n",length);

	SampleRate=get_leuint32(bytes+0x19);
	LOG_FORMATS("Sample rate %u\n",SampleRate);

	NumberOfPulses=get_leuint32(bytes+0x1d);
	LOG_FORMATS("Number Of Pulses %u\n",NumberOfPulses);

	CompressionType=bytes[0x21];
	Flags=bytes[0x22];
	HeaderExtensionLength=bytes[0x23];

	if ((Flags&0)==0)
	{
		Bit=-100;
	}
	else
	{
		Bit=100;
	}

	LOG_FORMATS("CompressionType %u   Flast %u   HeaderExtensionLength %u\n",CompressionType,Flags,HeaderExtensionLength);


	//from here on down for now I am assuming it is compressed csw file.
	in_ptr = (uint8_t*) bytes+0x34+HeaderExtensionLength;

	gz_ptr.resize( 8 );

	d_stream.next_in = (unsigned char *)in_ptr;
	d_stream.avail_in = mycaslen - ( in_ptr - bytes );
	d_stream.total_in=0;

	d_stream.next_out = &gz_ptr[0];
	d_stream.avail_out = 1;
	d_stream.total_out=0;

	d_stream.zalloc = nullptr;
	d_stream.zfree = nullptr;
	d_stream.opaque = nullptr;
	d_stream.data_type=0;

	err = inflateInit( &d_stream );
	if ( err != Z_OK )
	{
		LOG_FORMATS( "inflateInit2 error: %d\n", err );
		goto cleanup;
	}

	total_size=0;

	do
	{
		d_stream.next_out = &gz_ptr[0];
		d_stream.avail_out=1;
		err=inflate( &d_stream, Z_SYNC_FLUSH );
		if (err==Z_OK)
		{
			bsize=gz_ptr[0];
			if (bsize==0)
			{
				d_stream.avail_out=4;
				d_stream.next_out = &gz_ptr[0];
				err=inflate( &d_stream, Z_SYNC_FLUSH );
				bsize=get_leuint32(&gz_ptr[0]);
			}
			for (i=0;i<bsize;i++)
			{
				buffer[total_size++]=Bit;
			}
			Bit=-Bit;
		}
	}
	while (err==Z_OK);

	if ( err != Z_STREAM_END )
	{
		LOG_FORMATS( "inflate error: %d\n", err );
		goto cleanup;
	}

	err = inflateEnd( &d_stream );
	if ( err != Z_OK )
	{
		LOG_FORMATS( "inflateEnd error: %d\n", err );
		goto cleanup;
	}

	return length;

cleanup:
	return -1;
}
예제 #5
0
파일: csw_cas.c 프로젝트: cdenix/psmame
static int csw_cas_to_wav_size( const UINT8 *casdata, int caslen ) {
UINT32 SampleRate;
UINT32 NumberOfPulses;
UINT8  MajorRevision;
UINT8  MinorRevision;
UINT8  CompressionType;
UINT8  Flags;
UINT8  HeaderExtensionLength;
UINT8 *gz_ptr = NULL;

int			total_size;
z_stream	d_stream;
int 		err;
UINT8		*in_ptr;
int 		bsize=0;

	if ( memcmp( casdata, CSW_HEADER, sizeof(CSW_HEADER) ) ) {
		logerror( "csw_cas_to_wav_size: cassette image has incompatible header\n" );
		goto cleanup;
	}

	if (casdata[0x16]!=0x1a) {
		logerror( "csw_cas_to_wav_size: Terminator Code Not Found\n" );
		goto cleanup;
	}

	MajorRevision=casdata[0x17];
	MinorRevision=casdata[0x18];

	logerror("Version %d : %d\n",MajorRevision,MinorRevision);

	if (casdata[0x17]!=2){
		logerror( "csw_cas_to_wav_size: Unsuported Major Version\n" );
		goto cleanup;
	}

	SampleRate=get_leuint32(casdata+0x19);
	logerror("Sample rate %d\n",SampleRate);

	NumberOfPulses=get_leuint32(casdata+0x1d);
	logerror("Number Of Pulses %d\n",NumberOfPulses);


	CompressionType=casdata[0x21];
	Flags=casdata[0x22];
	HeaderExtensionLength=casdata[0x23];

	logerror("CompressionType %d   Flast %d   HeaderExtensionLength %d\n",CompressionType,Flags,HeaderExtensionLength);

	mycaslen=caslen;
	//from here on down for now I am assuming it is compressed csw file.
	in_ptr = (UINT8*) casdata+0x34+HeaderExtensionLength;

	gz_ptr = (UINT8*)malloc( 8 );


	d_stream.next_in = (unsigned char *)in_ptr;
	d_stream.avail_in = caslen - ( in_ptr - casdata );
	d_stream.total_in=0;

	d_stream.next_out = gz_ptr;
	d_stream.avail_out = 1;
	d_stream.total_out=0;

	d_stream.zalloc = 0;
	d_stream.zfree = 0;
	d_stream.opaque = 0;
	d_stream.data_type=0;

	err = inflateInit( &d_stream );
	if ( err != Z_OK ) {
		logerror( "inflateInit2 error: %d\n", err );
		goto cleanup;
	}


	total_size=1;
	do
	{
		d_stream.next_out = gz_ptr;
		d_stream.avail_out=1;
		err=inflate( &d_stream, Z_SYNC_FLUSH );
		if (err==Z_OK) {
			bsize=gz_ptr[0];
			if (bsize==0) {
				d_stream.avail_out=4;
				d_stream.next_out = gz_ptr;
				err=inflate( &d_stream, Z_SYNC_FLUSH );
				bsize=get_leuint32(gz_ptr);
			}
			total_size=total_size+bsize;
		}
	}
	while (err==Z_OK);

	if ( err != Z_STREAM_END ) {
		logerror( "inflate error: %d\n", err );
		goto cleanup;
	}

	err = inflateEnd( &d_stream );
	if ( err != Z_OK ) {
		logerror( "inflateEnd error: %d\n", err );
		goto cleanup;
	}






	if ( gz_ptr ) {
		free( gz_ptr );
		gz_ptr = NULL;
	}



	return total_size;

cleanup:
	if ( gz_ptr ) {
		free( gz_ptr );
		gz_ptr = NULL;
	}
	return -1;

}