Sign in to follow this  

DirectSound

This topic is 3456 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

I'm just trying to find a simple walkthrough of playing a wave file with DirectSound. The articles on this site are either way old or deal with DirectMusic and most of what I find from Google is for managed DX. Anybody have anything laying around? Not to be rude but I'm not interested in reading about using FMOD or any of the other third party audio libraries. I just need something simple for DirectSound.

Share this post


Link to post
Share on other sites
There aren't any one-liners for playing a wave file in DirectSound as there are in the mmio stuff.

However, there are several samples for DirectSound in the SDK. They use CSoundManager as a wrapper for creating the buffers, error checking, etc.

Just copy DXUTSound.cpp (if I remember) and DXUTSound.h to your project.

There's a macro something like DXUTErr(some message) used throughout the file so if you aren't using DXUT, just subsitute your favorite error reporting method (MessageBox, OutputDebugString, etc.).

It may appear to be a lot of code to do something simple but CSoundManager does it all for you.

You'll end up with something like

CSoundManager *sndMgr;
CSound *g_pSound;
...
g_pSound = NULL;
sndMgr = NULL;
...
if( sndMgr==NULL ) {
bool sndLoaded = InitSoundMgr();
if( sndLoaded ) {
g_pSound->Play( 0, DSBPLAY_LOOPING );
}
}
...
bool CD3DApp::InitSoundMgr()
{
HRESULT hr;

if( g_pSound )
{
g_pSound->Stop();
g_pSound->Reset();
}

SAFE_DELETE( g_pSound );
SAFE_DELETE( sndMgr );

sndMgr = new CSoundManager();
if( NULL == sndMgr )
{
MessageBox(NULL,"Failed to create sound mgr.","Error",MB_OK);
return false;
}

if( FAILED( hr = sndMgr->Initialize( m_hwnd, DSSCL_PRIORITY ) ) )
{
MessageBox( NULL, "Error initializing DirectSound.",
"Error", MB_OK | MB_ICONERROR );
return false;
}

if( FAILED( hr = sndMgr->SetPrimaryBufferFormat( 2, 22050, 16 ) ) )
{
MessageBox( NULL, "Error initializing DirectSound.",
"Error", MB_OK | MB_ICONERROR );
return false;
}
if( FAILED( hr = sndMgr->Create( &g_pSound, "your wave file name",0, GUID_NULL ) ) )
{
MessageBox(NULL,"Failed to create sound buffer for sound.","Creation Error",MB_OK);
return false;
}
return true;
}




You add dsound.lib to the link inputs for your project.

There may be another header or two you'll have to include but the SDK example will have those.

You'll also notice in the SDK examples you can set options in the Create call to control volume and frequency, etc. That's nice for engine sounds that depend on throttle positions, etc.

Share this post


Link to post
Share on other sites
On Flipcode there is a snippet to stream oggs with DirectSound. I modified that to load the entire file at once (its only sfx) then lock it to a soundbuffer. Then I have an array of soundbuffers that I copy to the sfx to when it actually gets played. Seems to work alright and its only around 150 lines.

Share this post


Link to post
Share on other sites
Quote:
Original post by stupid_programmer
On Flipcode there is a snippet to stream oggs with DirectSound. I modified that to load the entire file at once (its only sfx) then lock it to a soundbuffer. Then I have an array of soundbuffers that I copy to the sfx to when it actually gets played. Seems to work alright and its only around 150 lines.


From what I read at flipcode it looks like it requires the vorbis sdk...?

Apart from using those csound classes you can also use this code to load a wave.



//must be initialised
HWND window;

//initialised with the code below
LPDIRECTSOUND8 ds;
LPDIRECTSOUNDBUFFER buffer;

void initDs() {
DirectSoundCreate8(0, &ds, 0);
ds->SetCooperativeLevel(window, DSSCL_PRIORITY);

DSBUFFERDESC pdsbd = {0};
pdsbd.dwSize = sizeof(DSBUFFERDESC);
pdsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;

WAVEFORMATEX wfx = {0};
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 2;
wfx.nSamplesPerSec = 22050;
wfx.wBitsPerSample = 16;
wfx.nBlockAlign = WORD(wfx.wBitsPerSample / 8 * wfx.nChannels);
wfx.nAvgBytesPerSec = DWORD(wfx.nSamplesPerSec * wfx.nBlockAlign);

LPDIRECTSOUNDBUFFER pDSBPrimary;
ds->CreateSoundBuffer(&pdsbd, &pDSBPrimary, 0);
pDSBPrimary->SetFormat(&wfx);
pDSBPrimary->Release();
}

void loadWave() {
std::string fileName = "snd.wav";

char* f = new char[fileName.length()+1];

for(unsigned int j=0;j<fileName.length();j++) {
f[j] = fileName[j];
}

f[fileName.length()] = '\0';
HMMIO m_hmmio = mmioOpen(f, 0, MMIO_ALLOCBUF|MMIO_READ);
delete [] f;

MMCKINFO m_ckRiff;
mmioDescend(m_hmmio, &m_ckRiff, 0, 0);
MMCKINFO ckIn;
ckIn.ckid = mmioFOURCC('f','m','t',' ');
mmioDescend(m_hmmio, &ckIn, &m_ckRiff, MMIO_FINDCHUNK);

PCMWAVEFORMAT pcmWaveFormat;
mmioRead(m_hmmio, (HPSTR)&pcmWaveFormat, sizeof(pcmWaveFormat));
WAVEFORMATEX* m_pwfx = 0;
m_pwfx = (WAVEFORMATEX*)new CHAR[sizeof(WAVEFORMATEX)];
memcpy(m_pwfx, &pcmWaveFormat, sizeof(pcmWaveFormat));
m_pwfx->cbSize = 0;
mmioAscend(m_hmmio, &ckIn, 0);
mmioSeek(m_hmmio, m_ckRiff.dwDataOffset + sizeof(FOURCC), SEEK_SET);
MMCKINFO m_ck;
m_ck.ckid = mmioFOURCC('d','a','t','a');
mmioDescend(m_hmmio, &m_ck, &m_ckRiff, MMIO_FINDCHUNK);

DSBUFFERDESC dsbd = {0};
dsbd.dwSize = sizeof(DSBUFFERDESC);
dsbd.dwFlags = (m_pwfx->nChannels == 1)?DSBCAPS_CTRL3D|DSBCAPS_CTRLVOLUME:DSBCAPS_CTRLVOLUME; //if mono use 3d flags, otherwise ..
dsbd.dwBufferBytes = m_ck.cksize;
dsbd.guid3DAlgorithm = DS3DALG_DEFAULT;
dsbd.lpwfxFormat = m_pwfx;

ds->CreateSoundBuffer(&dsbd, &buffer, 0);

VOID* pDSLockedBuffer = 0;
DWORD dwSizeToRead;
buffer->Lock(0, m_ck.cksize, &pDSLockedBuffer, &dwSizeToRead, 0, 0, 0L);
BYTE* pBuffer = (BYTE*) pDSLockedBuffer;
MMIOINFO mmioinfoIn;
mmioGetInfo(m_hmmio, &mmioinfoIn, 0);
UINT cbDataIn = (dwSizeToRead > m_ck.cksize)?m_ck.cksize:dwSizeToRead;
m_ck.cksize -= cbDataIn;

for(DWORD cT=0;cT<cbDataIn;cT++) {
if(mmioinfoIn.pchNext == mmioinfoIn.pchEndRead) {
mmioAdvance( m_hmmio, &mmioinfoIn, MMIO_READ);
}

*((BYTE*)pBuffer+cT) = *((BYTE*)mmioinfoIn.pchNext);
mmioinfoIn.pchNext++;
}

mmioSetInfo(m_hmmio, &mmioinfoIn, 0);

if(cbDataIn < dwSizeToRead) {
FillMemory((BYTE*)pDSLockedBuffer + cbDataIn, dwSizeToRead - cbDataIn, (BYTE)(m_pwfx->wBitsPerSample == 8?128:0));
}

buffer->Unlock(pDSLockedBuffer, dwSizeToRead, 0, 0);
mmioClose(m_hmmio, 0);
delete[] m_pwfx;
}

void cleanUp() {
buffer->Release();
ds->Release();
}





edit:
It might be safer to use the csound stuff, since it has error checking etc.

Share this post


Link to post
Share on other sites
Quote:
Original post by stupid_programmer
Thats more of something I was looking for. I thought there had to be a pretty straight forward way of loading in wav data.

Think I might just support ogg for streaming and ogg/wav for sound effects.
That's what I do, ogg has a nice and simple library, and wav is pretty straightforward too.

Share this post


Link to post
Share on other sites
Ok, stupid_programmer (no offense, lol), you make a good point. DirectSound tutorials are indeed hard to come by. I've written some DirectSound turorials and have posted them on my blog. You can view my blog on the bottom of my sig. Better yet, I'll give you direct links to the posts containing the tutorials. I've written 8 so far and hope to write more soon. They teach things beyond loading a .wav file if you need it :)

http://blueshogun96.wordpress.com/2008/05/19/directsound-programming-tutorials-lessons-1-6/

http://blueshogun96.wordpress.com/2008/06/07/directsound-tutorials-update-lesson-7-and-8/

There's an EAX tutorial there too if you're interested. I hope this helps.

Share this post


Link to post
Share on other sites

This topic is 3456 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