示例#1
0
static bool
wava_Open (THIS_PTR, uio_DirHandle *dir, const char *filename)
{
	TFB_WaveSoundDecoder* wava = (TFB_WaveSoundDecoder*) This;
	WAVFileHdr_Struct FileHdr;
	WAVChunkHdr_Struct ChunkHdr;

	wava->fp = uio_fopen (dir, filename, "rb");
	if (!wava->fp)
	{
		wava->last_error = errno;
		return false;
	}

	wava->data_size = 0;
	wava->data_ofs = 0;

	// read wave header
	if (!wava_readFileHeader (wava, &FileHdr))
	{
		wava->last_error = errno;
		wava_Close (This);
		return false;
	}
	if (FileHdr.Id != RIFF || FileHdr.Type != WAVE)
	{
		log_add (log_Warning, "wava_Open(): "
				"not a wave file, ID 0x%08x, Type 0x%08x",
				FileHdr.Id, FileHdr.Type);
		wava_Close (This);
		return false;
	}

	for (FileHdr.Size = ((FileHdr.Size + 1) & ~1) - 4; FileHdr.Size != 0;
			FileHdr.Size -= (((ChunkHdr.Size + 1) & ~1) + 8))
	{
		if (!wava_readChunkHeader (wava, &ChunkHdr))
		{
			wava->last_error = errno;
			wava_Close (This);
			return false;
		}

		if (ChunkHdr.Id == FMT)
		{
			if (!wava_readFormatHeader (wava, &wava->FmtHdr))
			{
				wava->last_error = errno;
				wava_Close (This);
				return false;
			}
			uio_fseek (wava->fp, ChunkHdr.Size - 16, SEEK_CUR);
		}
		else
		{
			if (ChunkHdr.Id == DATA)
			{
				wava->data_size = ChunkHdr.Size;
				wava->data_ofs = uio_ftell (wava->fp);
			}
			uio_fseek (wava->fp, ChunkHdr.Size, SEEK_CUR);
		}

		uio_fseek (wava->fp, ChunkHdr.Size & 1, SEEK_CUR);
	}

	if (!wava->data_size || !wava->data_ofs)
	{
		log_add (log_Warning, "wava_Open(): bad wave file,"
				" no DATA chunk found");
		wava_Close (This);
		return false;
	}

	if (wava->FmtHdr.Format == 0x0001)
	{
		This->format = (wava->FmtHdr.Channels == 1 ?
				(wava->FmtHdr.BitsPerSample == 8 ?
					wava_formats->mono8 : wava_formats->mono16)
				:
				(wava->FmtHdr.BitsPerSample == 8 ?
					wava_formats->stereo8 : wava_formats->stereo16)
				);
		This->frequency = wava->FmtHdr.SamplesPerSec;
	} 
	else
	{
		log_add (log_Warning, "wava_Open(): unsupported format %x",
				wava->FmtHdr.Format);
		wava_Close (This);
		return false;
	}

	uio_fseek (wava->fp, wava->data_ofs, SEEK_SET);
	wava->max_pcm = wava->data_size / wava->FmtHdr.BlockAlign;
	wava->cur_pcm = 0;
	This->length = (float) wava->max_pcm / wava->FmtHdr.SamplesPerSec;
	wava->last_error = 0;

	return true;
}
示例#2
0
static bool
wava_Open (THIS_PTR, uio_DirHandle *dir, const char *filename)
{
	TFB_WaveSoundDecoder* wava = (TFB_WaveSoundDecoder*) This;
	wave_FileHeader fileHdr;
	wave_ChunkHeader chunkHdr;

	wava->fp = uio_fopen (dir, filename, "rb");
	if (!wava->fp)
	{
		wava->last_error = errno;
		return false;
	}

	wava->data_size = 0;
	wava->data_ofs = 0;

	// read wave header
	if (!wava_readFileHeader (wava, &fileHdr))
	{
		wava->last_error = errno;
		wava_Close (This);
		return false;
	}
	if (fileHdr.id != wave_RiffID || fileHdr.type != wave_WaveID)
	{
		log_add (log_Warning, "wava_Open(): "
				"not a wave file, ID 0x%08x, Type 0x%08x",
				fileHdr.id, fileHdr.type);
		wava_Close (This);
		return false;
	}

	for (fileHdr.size = ((fileHdr.size + 1) & ~1) - 4; fileHdr.size != 0;
			fileHdr.size -= (((chunkHdr.size + 1) & ~1) + 8))
	{
		if (!wava_readChunkHeader (wava, &chunkHdr))
		{
			wava_Close (This);
			return false;
		}

		if (chunkHdr.id == wave_FmtID)
		{
			if (!wava_readFormatHeader (wava, &wava->fmtHdr))
			{
				wava_Close (This);
				return false;
			}
			uio_fseek (wava->fp, chunkHdr.size - 16, SEEK_CUR);
		}
		else
		{
			if (chunkHdr.id == wave_DataID)
			{
				wava->data_size = chunkHdr.size;
				wava->data_ofs = uio_ftell (wava->fp);
			}
			uio_fseek (wava->fp, chunkHdr.size, SEEK_CUR);
		}

		// 2-align the file ptr
		// XXX: I do not think this is necessary in WAVE files;
		//   possibly a remnant of ported AIFF reader
		uio_fseek (wava->fp, chunkHdr.size & 1, SEEK_CUR);
	}

	if (!wava->data_size || !wava->data_ofs)
	{
		log_add (log_Warning, "wava_Open(): bad wave file,"
				" no DATA chunk found");
		wava_Close (This);
		return false;
	}

	if (wava->fmtHdr.format != 0x0001)
	{	// not a PCM format
		log_add (log_Warning, "wava_Open(): unsupported format %x",
				wava->fmtHdr.format);
		wava_Close (This);
		return false;
	}
	if (wava->fmtHdr.channels != 1 && wava->fmtHdr.channels != 2)
	{
		log_add (log_Warning, "wava_Open(): unsupported number of channels %u",
				(unsigned)wava->fmtHdr.channels);
		wava_Close (This);
		return false;
	}

	This->format = (wava->fmtHdr.channels == 1 ?
			(wava->fmtHdr.bitsPerSample == 8 ?
				wava_formats->mono8 : wava_formats->mono16)
			:
			(wava->fmtHdr.bitsPerSample == 8 ?
				wava_formats->stereo8 : wava_formats->stereo16)
			);
	This->frequency = wava->fmtHdr.samplesPerSec;

	uio_fseek (wava->fp, wava->data_ofs, SEEK_SET);
	wava->max_pcm = wava->data_size / wava->fmtHdr.blockAlign;
	wava->cur_pcm = 0;
	This->length = (float) wava->max_pcm / wava->fmtHdr.samplesPerSec;
	wava->last_error = 0;

	return true;
}