[Openal] Loading .wav using OpenAL SDK 1.1 for Windows
Casey Borders
thebeast.13 at gmail.com
Sat Nov 10 08:04:00 PST 2007
I have put together some code that works from looking at alut and some
various bits of code around the internet. I use it in my OgreAL project (
http://www.ogre3d.org/phpBB2addons/viewforum.php?f=10), which integrates
OpenAL seamlessly into the Ogre Rendering Engine(www.ogre3d.org). Anyway,
here's that bit of code.
try
{
mLoop = loop?AL_TRUE:AL_FALSE;
// buffers
char magic[5];
magic[4] = '\0';
unsigned char buffer32[4];
unsigned char buffer16[2];
// check magic
CheckCondition(mSoundStream->read(magic, 4) == 4, 13, "Cannot read wav
file " + mFileName);
CheckCondition(std::string(magic) == "RIFF", 13, "Wrong wav file format.
This file is not a .wav file (no RIFF magic): " + mFileName);
// The next 4 bytes are the file size, we can skip this since we get the
size from the DataStream
mSoundStream->skip(4);
mSize = static_cast<Size>(mSoundStream->size());
// check file format
CheckCondition(mSoundStream->read(magic, 4) == 4, 13, "Cannot read wav
file " + mFileName);
CheckCondition(std::string(magic) == "WAVE", 13, "Wrong wav file format.
This file is not a .wav file (no WAVE format): " + mFileName);
// check 'fmt ' sub chunk (1)
CheckCondition(mSoundStream->read(magic, 4) == 4, 13, "Cannot read wav
file " + mFileName);
CheckCondition(std::string(magic) == "fmt ", 13, "Wrong wav file format.
This file is not a .wav file (no 'fmt ' subchunk): " + mFileName);
// read (1)'s size
CheckCondition(mSoundStream->read(buffer32, 4) == 4, 13, "Cannot read
wav file " + mFileName);
unsigned long subChunk1Size = readByte32(buffer32);
CheckCondition(subChunk1Size >= 16, 13, "Wrong wav file format. This
file is not a .wav file ('fmt ' chunk too small, truncated file?): " +
mFileName);
// check PCM audio format
CheckCondition(mSoundStream->read(buffer16, 2) == 2, 13, "Cannot read
wav file " + mFileName);
unsigned short audioFormat = readByte16(buffer16);
CheckCondition(audioFormat == 1, 13, "Wrong wav file format. This file
is not a .wav file (audio format is not PCM): " + mFileName);
// read number of channels
CheckCondition(mSoundStream->read(buffer16, 2) == 2, 13, "Cannot read
wav file " + mFileName);
unsigned short channels = readByte16(buffer16);
// read frequency (sample rate)
CheckCondition(mSoundStream->read(buffer32, 4) == 4, 13, "Cannot read
wav file " + mFileName);
mFreq = readByte32(buffer32);
// skip 6 bytes (Byte rate (4), Block align (2))
mSoundStream->skip(6);
// read bits per sample
CheckCondition(mSoundStream->read(buffer16, 2) == 2, 13, "Cannot read
wav file " + mFileName);
unsigned short bps = readByte16(buffer16);
if (channels == 1)
{
if(bps == 8)
{
mFormat = AL_FORMAT_MONO8;
// Set BufferSize to 250ms (Frequency divided by 4 (quarter of a
second))
mBufferSize = mFreq / 4;
}
else
{
mFormat = AL_FORMAT_MONO16;
// Set BufferSize to 250ms (Frequency * 2 (16bit) divided by 4
(quarter of a second))
mBufferSize = mFreq >> 1;
// IMPORTANT : The Buffer Size must be an exact multiple of the
BlockAlignment ...
mBufferSize -= (mBufferSize % 2);
}
}
else
{
if(bps == 8)
{
mFormat = AL_FORMAT_STEREO16;
// Set BufferSize to 250ms (Frequency * 2 (8bit stereo) divided
by 4 (quarter of a second))
mBufferSize = mFreq >> 1;
// IMPORTANT : The Buffer Size must be an exact multiple of the
BlockAlignment ...
mBufferSize -= (mBufferSize % 2);
}
else
{
mFormat = AL_FORMAT_STEREO16;
// Set BufferSize to 250ms (Frequency * 4 (16bit stereo) divided
by 4 (quarter of a second))
mBufferSize = mFreq;
// IMPORTANT : The Buffer Size must be an exact multiple of the
BlockAlignment ...
mBufferSize -= (mBufferSize % 4);
}
}
// check 'data' sub chunk (2)
CheckCondition(mSoundStream->read(magic, 4) == 4, 13, "Cannot read wav
file " + mFileName);
CheckCondition(std::string(magic) == "data" || std::string(magic) ==
"fact", 13, "Wrong wav file format. This file is not a .wav file (no data
subchunk): " + mFileName);
// fact is an option section we don't need to worry about
if(std::string(magic) == "fact")
{
mSoundStream->skip(8);
// Now we shoudl hit the data chunk
CheckCondition(mSoundStream->read(magic, 4) == 4, 13, "Cannot read
wav file " + mFileName);
CheckCondition(std::string(magic) == "data", 13, "Wrong wav file
format. This file is not a .wav file (no data subchunk): " + mFileName);
}
// The next four bytes are the size remaing of the file
CheckCondition(mSoundStream->read(buffer32, 4) == 4, 13, "Cannot read
wav file " + mFileName);
unsigned long remainingSize = readByte32(buffer32);
mDataStart = mSoundStream->tell();
mBuffers = new BufferRef[mNumBuffers];
alGenBuffers(mNumBuffers, mBuffers);
CheckError(alGetError(), "Could not generate buffer");
for(int i = 0; i < mNumBuffers; i++)
{
CheckCondition(AL_NONE != mBuffers[i], 13, "Could not generate
buffer");
Buffer buffer = bufferData(mSoundStream,
mStream?mBufferSize:remainingSize);
alBufferData(mBuffers[i], mFormat, &buffer[0], static_cast<Size>(
buffer.size()), mFreq);
CheckError(alGetError(), "Could not load buffer data");
}
}
catch(Ogre::Exception e)
{
for(int i = 0; i < mNumBuffers; i++)
{
if (mBuffers[i] && alIsBuffer(mBuffers[i]) == AL_TRUE)
{
alDeleteBuffers(1, &mBuffers[i]);
CheckError(alGetError(), "Failed to delete Buffer");
}
}
throw (e);
}
In the code mSoundStream is an Ogre::DataStream, which is specific to Ogre,
but you could replace it with an std::istream, or you could use a FILE* and
replace the stream access with fread, etc.
On Nov 10, 2007 10:37 AM, Nana Yaw <supremestar at hotmail.com> wrote:
> Hello,
> I'm new to OpenAL. I'm want to load a simple .wav file and have it played
> but I'm having defficulties.
> alut is deprecated in SDK 1.1 and so visul studio .Net 2005 prevents me
> from using it.
>
> Is there any way around it? Please help.
>
> regards
>
> ------------------------------
> Invite your mail contacts to join your friends list with Windows Live
> Spaces. It's easy! Try it!<http://spaces.live.com/spacesapi.aspx?wx_action=create&wx_url=/friends.aspx&mkt=en-us>
>
> _______________________________________________
> Openal mailing list
> Openal at opensource.creative.com
> http://opensource.creative.com/mailman/listinfo/openal
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://opensource.creative.com/pipermail/openal/attachments/20071110/6848e772/attachment.html
More information about the Openal
mailing list