Sign in to follow this  

DirectSound: Loadng a WAV file to a buffer.

This topic is 4811 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hey guys. what are the key functions ill need to load a WAV file from a path into a static buffer? i cant find in the directx 9 sdk docs what to do. VB has CreateSoundBufferFromFile, am i looking for something similar? any help you guys can provide would help. im not using DirectMusic, and id appreciate a tutorial that is comprehensive to getting a wav file loaded and playing with DirectSound. im using dx8.

Share this post


Link to post
Share on other sites
ive spent all day reviewing the few examples of direct sound initialization, loading, and playback i can find on gd.net and through google searchs. everyone uses their own object oriented systems that bury the detail im looking for. every single tutorial is like "the code for doing this is really long and hard to undetstand, so we/I did it for you! cut and paste this..."

does ANYONE have a straight forward way to load a WAV file into a buffer? static, streaming, anything.

is directmusic this much trouble?

Share this post


Link to post
Share on other sites
i guess this isnt a very popular subject. i understand.

im going to stop trying to reinvent the wheel and im going to use the sound system used in dsutil.h and dsutil.cpp. they do what im trying to do.

Share this post


Link to post
Share on other sites
The problem of loading a wave file into a static buffer is that you have to know about the wavefile. When you use Disrect Sound in low level (like I do) with no classes to bury all the dirty work, you have to set all the features of your buffer. For example, stereo, mono, 8 bit, 16 bit, sample rate, etc. There is a bunch of junk.

So at the header of every WAV file is all that junk. So you have to read in the wave file, examine the header, format your DirectSound buffers accordingly, and then from the header find where the actual data starts. Once you have your buffers formatted properly, you can read in the data and start the old 'Play()' function.

That's a lot of annoying work. I do not know the details of the WAV file header. But all classes which read in a wave file and play them in a Direct Sound buffer have to go through all those stages.

The only addition when considering streaming data is that you have to set up some kind of notification (be careful...put in the write flags when you create your buffer) that will signal your write thread to load more data into the DS buffer. You have to do this far enough ahead of time so that you don't disrupt the flow. That also means keeping track of where you are in the file so you can read the next bunch of data.

Hope this makes sense.

Brian

PS I have not looked at this site for a couple of months. So I just saw your message today.

Share this post


Link to post
Share on other sites
Opps! A confusing typo:

I meant "put in the CORRECT flags" not "put in the write flags" in that latter paragraph. That typo could really lead to confusion!

Brian

Share this post


Link to post
Share on other sites
this is what i use, anyway..

Sound::Sound(String filename, DWORD flags)
{
m_pDSB=NULL;
m_BufferSize=0;
m_CreationFlags=0;
m_looping=0;

if(flags & DSBCAPS_CTRL3D) RuntimeError("DSBCAPS_CTRL3D is not a valid flag for 2D sounds!");

filename=AbsolutePath(filename);
File* f=ReadFile(filename);
if(!f) { RuntimeError("Could not open WAV file!"); }

String sig=ReadCharacters(f,4);
if(sig!="RIFF") { CloseFile(f); RuntimeError("File is not a valid WAV file"); }

SeekFile(f,8);
sig=ReadCharacters(f,4);
if(sig!="WAVE") { CloseFile(f); RuntimeError("File is not a valid WAV file"); }

sig=ReadCharacters(f,4);
if(sig!="fmt ") { CloseFile(f); RuntimeError("File is not a valid WAV file"); }

SeekFile(f,20);
int type=ReadShort(f);
if(type!=0x0001) { CloseFile(f); RuntimeError("File is some stupid compressed WAV that\nI don't feel like bothering with."); }

WORD channels=ReadShort(f);
if(channels>2) { CloseFile(f); RuntimeError("File is a WAV with more than 2 channels.\nGo make it stereo."); }

WAVEFORMATEX wave;
ZeroMemory(&wave,sizeof(wave));
wave.wFormatTag=WAVE_FORMAT_PCM;
wave.nChannels=channels;
wave.nSamplesPerSec=ReadInt(f); ReadInt(f); ReadShort(f);
wave.wBitsPerSample=ReadShort(f);

if(!(wave.wBitsPerSample==8 || wave.wBitsPerSample==16))
{
CloseFile(f);
RuntimeError("WAV file is not a valid bitrate (8 or 16)");
}

wave.nBlockAlign=(wave.nChannels*wave.wBitsPerSample)/8;
wave.nAvgBytesPerSec=wave.nSamplesPerSec*wave.nBlockAlign;

sig=ReadCharacters(f,4);
if(sig!="data") { CloseFile(f); RuntimeError("File is not a valid WAV file"); }

DSBUFFERDESC desc;
ZeroMemory(&desc,sizeof(desc));
desc.dwSize=sizeof(desc);
desc.dwFlags=m_CreationFlags=flags|DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_LOCDEFER;
desc.dwBufferBytes=m_BufferSize=ReadInt(f);
desc.lpwfxFormat=&wave;

HRESULT hr;

if(FAILED(hr=gpDSound->CreateSoundBuffer(&desc,&m_pDSB,NULL)))
{ CloseFile(f); DXRuntimeError("Could not create sound buffer!",hr); }

unsigned char* data;
DWORD size;
if(FAILED(hr=m_pDSB->Lock(0,0,(void**)&data,&size,NULL,0,DSBLOCK_ENTIREBUFFER)))
{ CloseFile(f); DXRuntimeError("Could not lock sound buffer",hr); }

ReadPtr(f,data,size);

CloseFile(f);

if(FAILED(hr=m_pDSB->Unlock(data,size,NULL,0)))
DXRuntimeError("Could not unlock sound buffer",hr);

SoundVec.push_back(this);
}


there are some proprietary functions in there (namely, my File functions and my RuntimeError() function) but you get the idea. most of my file functions are just very thin wrappers over the slightly lower-level fopen/fread functions. WAV files are not really that complicated.. it's just the sheer number of different types that you have to deal with that makes it annoying.

this particular function will only load 8- or 16-bit, mono or stereo WAVs, which are proabably 99.999% of the WAVs you'll come across. it also only handles WAVs that store their data in one big chunk - no DATA and SLNT chunks. and no compression either.

Share this post


Link to post
Share on other sites
Hey, how did you get your code post to show up in that nifty scrollable highlighted text box..?

Just wondering. Its a great way to post code so people don't have to scroll to heck and back to get to the next reply, and to separate msg from code...

Share this post


Link to post
Share on other sites

This topic is 4811 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this