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; }
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; }