Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- bool AudioBuffer::readWAV(ResourceObject *obj)
- {
- WAVChunkHdr chunkHdr;
- WAVFmtExHdr fmtExHdr;
- WAVFileHdr fileHdr;
- WAVSmplHdr smplHdr;
- WAVFmtHdr fmtHdr;
- ALenum format = AL_FORMAT_MONO16;
- char *data = NULL;
- ALsizei size = 0;
- ALsizei freq = 22050;
- ALboolean loop = AL_FALSE;
- Stream *stream = ResourceManager->openStream(obj);
- if (!stream)
- return false;
- stream->read(4, &fileHdr.id[0]);
- stream->read(&fileHdr.size);
- stream->read(4, &fileHdr.type[0]);
- fileHdr.size=((fileHdr.size+1)&~1)-4;
- stream->read(4, &chunkHdr.id[0]);
- stream->read(&chunkHdr.size);
- // unread chunk data rounded up to nearest WORD
- S32 chunkRemaining = chunkHdr.size + (chunkHdr.size&1);
- while ((fileHdr.size!=0) && (stream->getStatus() != Stream::EOS))
- {
- // WAV Format header
- if (!dStrncmp((const char*)chunkHdr.id,"fmt ",4))
- {
- stream->read(&fmtHdr.format);
- stream->read(&fmtHdr.channels);
- stream->read(&fmtHdr.samplesPerSec);
- stream->read(&fmtHdr.bytesPerSec);
- stream->read(&fmtHdr.blockAlign);
- stream->read(&fmtHdr.bitsPerSample);
- if (fmtHdr.format==0x0001)
- {
- format=(fmtHdr.channels==1?
- (fmtHdr.bitsPerSample==8?AL_FORMAT_MONO8:AL_FORMAT_MONO16):
- (fmtHdr.bitsPerSample==8?AL_FORMAT_STEREO8:AL_FORMAT_STEREO16));
- freq=fmtHdr.samplesPerSec;
- chunkRemaining -= sizeof(WAVFmtHdr);
- }
- else
- {
- stream->read(sizeof(WAVFmtExHdr), &fmtExHdr);
- chunkRemaining -= sizeof(WAVFmtExHdr);
- }
- }
- // WAV Format header
- else if (!dStrncmp((const char*)chunkHdr.id,"data",4))
- {
- if (fmtHdr.format==0x0001)
- {
- size=chunkHdr.size;
- data=new char[chunkHdr.size];
- if (data)
- {
- stream->read(chunkHdr.size, data);
- #if defined(TORQUE_OS_MAC)
- // need to endian-flip the 16-bit data.
- if (fmtHdr.bitsPerSample==16) // !!!TBD we don't handle stereo, so may be RL flipped.
- {
- U16 *ds = (U16*)data;
- U16 *de = (U16*)(data+size);
- while (ds<de)
- {
- #if defined(TORQUE_BIG_ENDIAN)
- *ds = convertLEndianToHost(*ds);
- #else
- *ds = convertBEndianToHost(*ds);
- #endif
- ds++;
- }
- }
- #endif
- chunkRemaining -= chunkHdr.size;
- }
- else
- break;
- }
- else if (fmtHdr.format==0x0011)
- {
- //IMA ADPCM
- }
- else if (fmtHdr.format==0x0055)
- {
- //MP3 WAVE
- }
- }
- // WAV Loop header
- else if (!dStrncmp((const char*)chunkHdr.id,"smpl",4))
- {
- // this struct read is NOT endian safe but it is ok because
- // we are only testing the loops field against ZERO
- stream->read(sizeof(WAVSmplHdr), &smplHdr);
- loop = (smplHdr.loops ? AL_TRUE : AL_FALSE);
- chunkRemaining -= sizeof(WAVSmplHdr);
- }
- // either we have unread chunk data or we found an unknown chunk type
- // loop and read up to 1K bytes at a time until we have
- // read to the end of this chunk
- char buffer[1024];
- AssertFatal(chunkRemaining >= 0, "AudioBuffer::readWAV: remaining chunk data should never be less than zero.");
- while (chunkRemaining > 0)
- {
- S32 readSize = getMin(1024, chunkRemaining);
- stream->read(readSize, buffer);
- chunkRemaining -= readSize;
- }
- fileHdr.size-=(((chunkHdr.size+1)&~1)+8);
- // read next chunk header...
- stream->read(4, &chunkHdr.id[0]);
- stream->read(&chunkHdr.size);
- // unread chunk data rounded up to nearest WORD
- chunkRemaining = chunkHdr.size + (chunkHdr.size&1);
- }
- ResourceManager->closeStream(stream);
- if (data)
- {
- alBufferData(malBuffer, format, data, size, freq);
- delete [] data;
- return (alGetError() == AL_NO_ERROR);
- }
- return false;
- }
Advertisement
Add Comment
Please, Sign In to add comment