use RageFile

This commit is contained in:
Glenn Maynard
2003-12-04 20:21:08 +00:00
parent 5c2eb8acfe
commit 162e79ea83
2 changed files with 52 additions and 61 deletions
+44 -54
View File
@@ -23,13 +23,11 @@
* This file written by Ryan C. Gordon. ([email protected]) * This file written by Ryan C. Gordon. ([email protected])
*/ */
#include <global.h> #include "global.h"
#include "RageSoundReader_WAV.h" #include "RageSoundReader_WAV.h"
#include "RageLog.h" #include "RageLog.h"
#include "RageUtil.h" #include "RageUtil.h"
#include <stdio.h>
#include <errno.h>
#include <SDL_endian.h> #include <SDL_endian.h>
#define BAIL_IF_MACRO(c, e, r) if (c) { SetError(e); return r; } #define BAIL_IF_MACRO(c, e, r) if (c) { SetError(e); return r; }
@@ -64,24 +62,24 @@ Uint32 RageSoundReader_WAV::ConvertBytePosToMs(int BytesPerSample, int channels,
} }
/* Better than SDL_ReadLE16, since you can detect i/o errors... */ /* Better than SDL_ReadLE16, since you can detect i/o errors... */
bool RageSoundReader_WAV::read_le16(FILE *rw, Sint16 *si16) const bool RageSoundReader_WAV::read_le16( RageFile &f, Sint16 *si16 ) const
{ {
int rc = fread( si16, sizeof (Sint16), 1, rw ); const int ret = f.Read( si16, sizeof(Sint16) );
if( rc != 1 ) if( ret != sizeof(Sint16) )
{ {
SetError( feof(rw)? "end of file": strerror(errno) ); SetError( ret >= 0? "end of file": f.GetError().c_str() );
return false; return false;
} }
*si16 = SDL_SwapLE16( *si16 ); *si16 = SDL_SwapLE16( *si16 );
return true; return true;
} }
bool RageSoundReader_WAV::read_le16(FILE *rw, Uint16 *ui16) const bool RageSoundReader_WAV::read_le16( RageFile &f, Uint16 *ui16 ) const
{ {
int rc = fread( ui16, sizeof (Uint16), 1, rw ); const int ret = f.Read( ui16, sizeof(Uint16) );
if( rc != 1 ) if( ret != sizeof(Uint16) )
{ {
SetError( feof(rw)? "end of file": strerror(errno) ); SetError( ret >= 0? "end of file": f.GetError().c_str() );
return false; return false;
} }
*ui16 = SDL_SwapLE16(*ui16); *ui16 = SDL_SwapLE16(*ui16);
@@ -90,36 +88,36 @@ bool RageSoundReader_WAV::read_le16(FILE *rw, Uint16 *ui16) const
/* Better than SDL_ReadLE32, since you can detect i/o errors... */ /* Better than SDL_ReadLE32, since you can detect i/o errors... */
bool RageSoundReader_WAV::read_le32(FILE *rw, Sint32 *si32) const bool RageSoundReader_WAV::read_le32( RageFile &f, Sint32 *si32 ) const
{ {
int rc = fread( si32, sizeof (Sint32), 1, rw ); const int ret = f.Read( si32, sizeof(Sint32) );
if( rc != 1 ) if( ret != sizeof(Sint32) )
{ {
SetError( feof(rw)? "end of file": strerror(errno) ); SetError( ret >= 0? "end of file": f.GetError().c_str() );
return false; return false;
} }
*si32 = SDL_SwapLE32( *si32 ); *si32 = SDL_SwapLE32( *si32 );
return true; return true;
} }
bool RageSoundReader_WAV::read_le32(FILE *rw, Uint32 *ui32) const bool RageSoundReader_WAV::read_le32( RageFile &f, Uint32 *ui32 ) const
{ {
int rc = fread( ui32, sizeof (Uint32), 1, rw ); const int ret = f.Read( ui32, sizeof(Uint32) );
if( rc != 1 ) if( ret != sizeof(Uint32) )
{ {
SetError( feof(rw)? "end of file": strerror(errno) ); SetError( ret >= 0? "end of file": f.GetError().c_str() );
return false; return false;
} }
*ui32 = SDL_SwapLE32( *ui32 ); *ui32 = SDL_SwapLE32( *ui32 );
return true; return true;
} }
bool RageSoundReader_WAV::read_uint8(FILE *rw, Uint8 *ui8) const bool RageSoundReader_WAV::read_uint8( RageFile &f, Uint8 *ui8 ) const
{ {
int rc = fread( ui8, sizeof (Uint8), 1, rw ); const int ret = f.Read( ui8, sizeof(Uint8) );
if( rc != 1 ) if( ret != sizeof(Uint8) )
{ {
SetError( feof(rw)? "end of file": strerror(errno) ); SetError( ret >= 0? "end of file": f.GetError().c_str() );
return false; return false;
} }
return true; return true;
@@ -169,10 +167,10 @@ bool RageSoundReader_WAV::read_fmt_chunk()
int RageSoundReader_WAV::read_sample_fmt_normal(char *buf, unsigned len) int RageSoundReader_WAV::read_sample_fmt_normal(char *buf, unsigned len)
{ {
int ret = fread( buf, 1, len, this->rw ); const int ret = this->rw.Read( buf, len );
if( ret == -1 ) if( ret == -1 )
{ {
SetError( strerror(errno) ); SetError( ret >= 0? "end of file": rw.GetError().c_str() );
return -1; return -1;
} }
@@ -185,11 +183,11 @@ int RageSoundReader_WAV::seek_sample_fmt_normal( Uint32 ms )
const int offset = ConvertMsToBytePos( BytesPerSample, Channels, ms); const int offset = ConvertMsToBytePos( BytesPerSample, Channels, ms);
const int pos = (int) (this->fmt.data_starting_offset + offset); const int pos = (int) (this->fmt.data_starting_offset + offset);
int rc = fseek( this->rw, pos, SEEK_SET ); const int ret = this->rw.Seek( pos );
BAIL_IF_MACRO(rc == -1, strerror(errno), -1); BAIL_IF_MACRO( ret == -1, this->rw.GetError(), -1 );
/* If we seek past end of ifle, leave the cursor there, so subsequent reads will return EOF. */ /* If we seek past end of ifle, leave the cursor there, so subsequent reads will return EOF. */
if( pos >= (int) GetFileSizeInBytes( filename ) ) if( pos >= this->rw.GetFileSize() )
return 0; return 0;
return ms; return ms;
@@ -197,10 +195,9 @@ int RageSoundReader_WAV::seek_sample_fmt_normal( Uint32 ms )
int RageSoundReader_WAV::get_length_fmt_adpcm() const int RageSoundReader_WAV::get_length_fmt_adpcm() const
{ {
int ret = fseek(this->rw, 0, SEEK_END); this->rw.Rewind();
BAIL_IF_MACRO( ret == -1, strerror(errno), -1 );
int offset = ftell( this->rw ); int offset = this->rw.Tell();
offset -= fmt.data_starting_offset; offset -= fmt.data_starting_offset;
/* pcm bytes per block */ /* pcm bytes per block */
@@ -209,7 +206,7 @@ int RageSoundReader_WAV::get_length_fmt_adpcm() const
const int byteno = blockno * bpb; const int byteno = blockno * bpb;
/* Seek back to the beginning of the last frame and find out how long it really is. */ /* Seek back to the beginning of the last frame and find out how long it really is. */
fseek( this->rw, blockno * fmt.wBlockAlign + fmt.data_starting_offset, SEEK_SET ); this->rw.Seek( blockno * fmt.wBlockAlign + fmt.data_starting_offset );
/* Don't mess up this->adpcm; we'll put the cursor back as if nothing happened. */ /* Don't mess up this->adpcm; we'll put the cursor back as if nothing happened. */
adpcm_t tmp_adpcm(adpcm); adpcm_t tmp_adpcm(adpcm);
@@ -223,10 +220,7 @@ int RageSoundReader_WAV::get_length_fmt_adpcm() const
int RageSoundReader_WAV::get_length_fmt_normal() const int RageSoundReader_WAV::get_length_fmt_normal() const
{ {
int ret = fseek( this->rw, 0, SEEK_END ); const int offset = this->rw.GetFileSize();
BAIL_IF_MACRO( ret == -1, strerror(errno), -1 );
int offset = ftell( this->rw );
return ConvertBytePosToMs( BytesPerSample, Channels, offset - this->fmt.data_starting_offset); return ConvertBytePosToMs( BytesPerSample, Channels, offset - this->fmt.data_starting_offset);
} }
@@ -364,8 +358,8 @@ int RageSoundReader_WAV::seek_sample_fmt_adpcm( Uint32 ms )
const int skipsize = (offset / bpb) * this->fmt.wBlockAlign; const int skipsize = (offset / bpb) * this->fmt.wBlockAlign;
const int pos = skipsize + this->fmt.data_starting_offset; const int pos = skipsize + this->fmt.data_starting_offset;
int rc = fseek(this->rw, pos, SEEK_SET); int rc = this->rw.Seek( pos );
BAIL_IF_MACRO(rc == -1, strerror(errno), -1); BAIL_IF_MACRO(rc == -1, this->rw.GetError(), -1);
/* The offset we need is in this block, so we need to decode to there. */ /* The offset we need is in this block, so we need to decode to there. */
rc = offset % bpb; /* bytes into this block we need to decode */ rc = offset % bpb; /* bytes into this block we need to decode */
@@ -402,7 +396,7 @@ int RageSoundReader_WAV::seek_sample_fmt_adpcm( Uint32 ms )
/* Locate a chunk by ID. */ /* Locate a chunk by ID. */
int RageSoundReader_WAV::find_chunk( Uint32 id, Sint32 &size ) int RageSoundReader_WAV::find_chunk( Uint32 id, Sint32 &size )
{ {
Uint32 pos = ftell(rw); Uint32 pos = this->rw.Tell();
while (1) while (1)
{ {
Uint32 id_ = 0; Uint32 id_ = 0;
@@ -418,10 +412,10 @@ int RageSoundReader_WAV::find_chunk( Uint32 id, Sint32 &size )
return false; return false;
pos += (sizeof (Uint32) * 2) + size; pos += (sizeof (Uint32) * 2) + size;
int ret = fseek(rw, pos, SEEK_SET); int ret = this->rw.Seek( pos );
if( ret == -1 ) if( ret == -1 )
{ {
SetError( strerror(errno) ); SetError( this->rw.GetError() );
return false; return false;
} }
} }
@@ -449,7 +443,7 @@ SoundReader_FileReader::OpenResult RageSoundReader_WAV::WAV_open_internal()
Sint32 NextChunk; Sint32 NextChunk;
BAIL_IF_MACRO(!find_chunk(fmtID, NextChunk), "No format chunk.", OPEN_MATCH_BUT_FAIL); BAIL_IF_MACRO(!find_chunk(fmtID, NextChunk), "No format chunk.", OPEN_MATCH_BUT_FAIL);
NextChunk += ftell(rw); NextChunk += this->rw.Tell();
BAIL_IF_MACRO(!read_fmt_chunk(), "Can't read format chunk.", OPEN_MATCH_BUT_FAIL); BAIL_IF_MACRO(!read_fmt_chunk(), "Can't read format chunk.", OPEN_MATCH_BUT_FAIL);
/* I think multi-channel WAVs are possible, but I've never even seen one. */ /* I think multi-channel WAVs are possible, but I've never even seen one. */
@@ -493,12 +487,12 @@ SoundReader_FileReader::OpenResult RageSoundReader_WAV::WAV_open_internal()
if( Channels == 1 ) if( Channels == 1 )
Input_Buffer_Ratio *= 2; Input_Buffer_Ratio *= 2;
fseek(rw, NextChunk, SEEK_SET ); this->rw.Seek( NextChunk );
Sint32 DataSize; Sint32 DataSize;
BAIL_IF_MACRO(!find_chunk(dataID, DataSize), "No data chunk.", OPEN_MATCH_BUT_FAIL); BAIL_IF_MACRO(!find_chunk(dataID, DataSize), "No data chunk.", OPEN_MATCH_BUT_FAIL);
fmt.data_starting_offset = ftell(rw); fmt.data_starting_offset = this->rw.Tell();
fmt.adpcm_sample_frame_size = BytesPerSample * Channels; fmt.adpcm_sample_frame_size = BytesPerSample * Channels;
return OPEN_OK; return OPEN_OK;
@@ -510,10 +504,9 @@ SoundReader_FileReader::OpenResult RageSoundReader_WAV::Open( CString filename_
Close(); Close();
Input_Buffer_Ratio = 1; Input_Buffer_Ratio = 1;
filename = filename_; filename = filename_;
rw = fopen(filename, "rb"); if( !this->rw.Open( filename ) )
if( !rw )
{ {
SetError( ssprintf("Couldn't open file: %s", strerror(errno)) ); SetError( ssprintf("Couldn't open file: %s", this->rw.GetError().c_str()) );
return OPEN_NO_MATCH; return OPEN_NO_MATCH;
} }
@@ -529,9 +522,7 @@ SoundReader_FileReader::OpenResult RageSoundReader_WAV::Open( CString filename_
void RageSoundReader_WAV::Close() void RageSoundReader_WAV::Close()
{ {
if( rw ) this->rw.Close();
fclose( rw );
rw = NULL;
} }
@@ -612,7 +603,7 @@ int RageSoundReader_WAV::SetPosition(int ms)
int RageSoundReader_WAV::GetLength() const int RageSoundReader_WAV::GetLength() const
{ {
const int origpos = ftell( this->rw ); const int origpos = this->rw.Tell();
int ret = 0; int ret = 0;
switch (this->fmt.wFormatTag) switch (this->fmt.wFormatTag)
@@ -625,15 +616,14 @@ int RageSoundReader_WAV::GetLength() const
break; break;
} }
int rc = fseek( this->rw, origpos, SEEK_SET ); int rc = this->rw.Seek( origpos );
BAIL_IF_MACRO( rc == -1, strerror(errno), -1 ); BAIL_IF_MACRO( rc == -1, this->rw.GetError(), -1 );
return ret; return ret;
} }
RageSoundReader_WAV::RageSoundReader_WAV() RageSoundReader_WAV::RageSoundReader_WAV()
{ {
rw = NULL;
} }
SoundReader *RageSoundReader_WAV::Copy() const SoundReader *RageSoundReader_WAV::Copy() const
+7 -6
View File
@@ -3,10 +3,11 @@
#include "RageSoundReader_FileReader.h" #include "RageSoundReader_FileReader.h"
#include "SDL_utils.h" #include "SDL_utils.h"
#include "RageFile.h"
class RageSoundReader_WAV: public SoundReader_FileReader class RageSoundReader_WAV: public SoundReader_FileReader
{ {
FILE *rw; mutable RageFile rw;
struct struct
{ {
Sint16 wFormatTag; Sint16 wFormatTag;
@@ -52,11 +53,11 @@ class RageSoundReader_WAV: public SoundReader_FileReader
enum { CONV_NONE, CONV_8BIT_TO_16BIT, CONV_16LSB_TO_16SYS } Conversion; enum { CONV_NONE, CONV_8BIT_TO_16BIT, CONV_16LSB_TO_16SYS } Conversion;
int read_sample_fmt_normal( char *buf, unsigned len ); int read_sample_fmt_normal( char *buf, unsigned len );
bool read_le16( FILE *rw, Sint16 *si16 ) const; bool read_le16( RageFile &f, Sint16 *si16 ) const;
bool read_le16( FILE *rw, Uint16 *ui16 ) const; bool read_le16( RageFile &f, Uint16 *ui16 ) const;
bool read_le32( FILE *rw, Sint32 *si32 ) const; bool read_le32( RageFile &f, Sint32 *si32 ) const;
bool read_le32( FILE *rw, Uint32 *ui32 ) const; bool read_le32( RageFile &f, Uint32 *ui32 ) const;
bool read_uint8( FILE *rw, Uint8 *ui8 ) const; bool read_uint8( RageFile &f, Uint8 *ui8 ) const;
bool read_adpcm_block_headers( adpcm_t &out ) const; bool read_adpcm_block_headers( adpcm_t &out ) const;
bool decode_adpcm_sample_frame(); bool decode_adpcm_sample_frame();