#include <wav_sound_file.hpp>
Inherits SoundFile.
Public Member Functions | |
WavSoundFile (PHYSFS_file *file) | |
~WavSoundFile () | |
size_t | read (void *buffer, size_t buffer_size) |
void | reset () |
Private Member Functions | |
WavSoundFile (const WavSoundFile &) | |
WavSoundFile & | operator= (const WavSoundFile &) |
Private Attributes | |
PHYSFS_file * | file |
PHYSFS_sint64 | datastart |
Definition at line 24 of file wav_sound_file.hpp.
WavSoundFile::WavSoundFile | ( | PHYSFS_file * | file | ) |
Definition at line 44 of file wav_sound_file.cpp.
References SoundFile::bits_per_sample, SoundFile::channels, datastart, file, log_debug, SoundFile::rate, read16LE(), read32LE(), and SoundFile::size.
00044 : 00045 file(file_), 00046 datastart() 00047 { 00048 assert(file); 00049 char magic[4]; 00050 if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1) 00051 throw SoundError("Couldn't read file magic (not a wave file)"); 00052 if(strncmp(magic, "RIFF", 4) != 0) { 00053 log_debug << "MAGIC: " << magic << std::endl; 00054 throw SoundError("file is not a RIFF wav file"); 00055 } 00056 00057 uint32_t wavelen = read32LE(file); 00058 (void) wavelen; 00059 00060 if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1) 00061 throw SoundError("Couldn't read chunk header (not a wav file?)"); 00062 if(strncmp(magic, "WAVE", 4) != 0) 00063 throw SoundError("file is not a valid RIFF/WAVE file"); 00064 00065 char chunkmagic[4]; 00066 uint32_t chunklen; 00067 00068 // search audio data format chunk 00069 do { 00070 if(PHYSFS_read(file, chunkmagic, sizeof(chunkmagic), 1) != 1) 00071 throw SoundError("EOF while searching format chunk"); 00072 chunklen = read32LE(file); 00073 00074 if(strncmp(chunkmagic, "fmt ", 4) == 0) 00075 break; 00076 00077 if(strncmp(chunkmagic, "fact", 4) == 0 00078 || strncmp(chunkmagic, "LIST", 4) == 0) { 00079 // skip chunk 00080 if(PHYSFS_seek(file, PHYSFS_tell(file) + chunklen) == 0) 00081 throw SoundError("EOF while searching fmt chunk"); 00082 } else { 00083 throw SoundError("complex WAVE files not supported"); 00084 } 00085 } while(true); 00086 00087 if(chunklen < 16) 00088 throw SoundError("Format chunk too short"); 00089 00090 // parse format 00091 uint16_t encoding = read16LE(file); 00092 if(encoding != 1) 00093 throw SoundError("only PCM encoding supported"); 00094 channels = read16LE(file); 00095 rate = read32LE(file); 00096 uint32_t byterate = read32LE(file); 00097 (void) byterate; 00098 uint16_t blockalign = read16LE(file); 00099 (void) blockalign; 00100 bits_per_sample = read16LE(file); 00101 00102 if(chunklen > 16) { 00103 if(PHYSFS_seek(file, PHYSFS_tell(file) + (chunklen-16)) == 0) 00104 throw SoundError("EOF while reading rest of format chunk"); 00105 } 00106 00107 // set file offset to DATA chunk data 00108 do { 00109 if(PHYSFS_read(file, chunkmagic, sizeof(chunkmagic), 1) != 1) 00110 throw SoundError("EOF while searching data chunk"); 00111 chunklen = read32LE(file); 00112 00113 if(strncmp(chunkmagic, "data", 4) == 0) 00114 break; 00115 00116 // skip chunk 00117 if(PHYSFS_seek(file, PHYSFS_tell(file) + chunklen) == 0) 00118 throw SoundError("EOF while searching fmt chunk"); 00119 } while(true); 00120 00121 datastart = PHYSFS_tell(file); 00122 size = static_cast<size_t> (chunklen); 00123 }
WavSoundFile::~WavSoundFile | ( | ) |
Definition at line 125 of file wav_sound_file.cpp.
References file.
00126 { 00127 PHYSFS_close(file); 00128 }
WavSoundFile::WavSoundFile | ( | const WavSoundFile & | ) | [private] |
size_t WavSoundFile::read | ( | void * | buffer, | |
size_t | buffer_size | |||
) | [virtual] |
Implements SoundFile.
Definition at line 138 of file wav_sound_file.cpp.
References SoundFile::bits_per_sample, datastart, file, and SoundFile::size.
00139 { 00140 PHYSFS_sint64 end = datastart + size; 00141 PHYSFS_sint64 cur = PHYSFS_tell(file); 00142 if(cur >= end) 00143 return 0; 00144 00145 size_t readsize = std::min(static_cast<size_t> (end - cur), buffer_size); 00146 if(PHYSFS_read(file, buffer, readsize, 1) != 1) 00147 throw SoundError("read error while reading samples"); 00148 00149 #ifdef WORDS_BIGENDIAN 00150 if (bits_per_sample != 16) 00151 return readsize; 00152 char *tmp = (char*)buffer; 00153 00154 size_t i; 00155 char c; 00156 for (i = 0; i < readsize / 2; i++) 00157 { 00158 c = tmp[2*i]; 00159 tmp[2*i] = tmp[2*i+1]; 00160 tmp[2*i+1] = c; 00161 } 00162 00163 buffer = tmp; 00164 #endif 00165 00166 return readsize; 00167 }
void WavSoundFile::reset | ( | ) | [virtual] |
Implements SoundFile.
Definition at line 131 of file wav_sound_file.cpp.
References datastart, and file.
00132 { 00133 if(PHYSFS_seek(file, datastart) == 0) 00134 throw SoundError("Couldn't seek to data start"); 00135 }
WavSoundFile& WavSoundFile::operator= | ( | const WavSoundFile & | ) | [private] |
PHYSFS_file* WavSoundFile::file [private] |
Definition at line 34 of file wav_sound_file.hpp.
Referenced by read(), reset(), WavSoundFile(), and ~WavSoundFile().
PHYSFS_sint64 WavSoundFile::datastart [private] |
Definition at line 36 of file wav_sound_file.hpp.
Referenced by read(), reset(), and WavSoundFile().