• Advertisement

Archived

This topic is now archived and is closed to further replies.

Using DirectSound and OggVorbis

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

Has anyone tried this? If so, are there any tutorials as to how to make this possible? I am having big problems doing this. All the examples that come with the OggVorbis SDK are for console applications.

Share this post


Link to post
Share on other sites
Advertisement
Well i searched the forum a while back and found this code...

Header file

#include <windows.h> // from your fave include dir ;)

#include <mmreg.h>

#include <dsound.h> // from the directx 8 sdk


#include "vorbis/codec.h" // from the vorbis sdk

#include "vorbis/vorbisfile.h" // also :)


#define BUFSIZE 65536*10 // buffer length


class OggPlayer
{
protected:

bool bInitialized; // initialized?

bool bFileOpened; // have we opened an ogg yet?


bool bReleaseDS; // release ds by ourselves?


LPDIRECTSOUND8 pDS; // the directsound 8 object


LPDIRECTSOUNDBUFFER pDSB; // the buffer


OggVorbis_File
vf; // for the vorbisfile interface


int nLastSection, // which half of the buffer

// are/were

nCurSection; // we playing?


bool bAlmostDone; // only one half of the buffer

// to play

bool bDone; // done playing

bool bLoop; // loop?


public:

OggPlayer();
~OggPlayer();

bool // initialize dsound ..

InitDirectSound( HWND hWnd );

inline void // .. or use already initialized

UseDirectSound( LPDIRECTSOUND8 _pDS )
{
pDS = _pDS;
}

bool // this opens an oggvorbis for

// playing

OpenOgg( char *filename );

void // and this one closes it :)

Close();

void // play it again sam

Play(bool loop = false);

void // stop it

Stop();

void // be sure to call this from

//time to time

Update();

inline bool IsPlaying()
{
return !bDone;
}
};


now for the cpp

OggPlayer::OggPlayer()
{
bFileOpened = false;
bInitialized = false;
bReleaseDS = false;
pDS = NULL;
pDSB = NULL;
bLoop = false;
bDone = false;
bAlmostDone = false;
}

OggPlayer::~OggPlayer()
{
if (bFileOpened)
Close();

if (bReleaseDS && pDS)
pDS->Release();
}

bool OggPlayer::InitDirectSound( HWND hWnd )
{
HRESULT hr;

if (FAILED(hr = DirectSoundCreate8(NULL, &pDS, NULL)))
return bInitialized = false;

pDS->Initialize(NULL);
pDS->SetCooperativeLevel( hWnd, DSSCL_PRIORITY );

bReleaseDS = true;

return bInitialized = true;
}

bool OggPlayer::OpenOgg( char *filename )
{
if (!bInitialized)
return false;

if (bFileOpened)
Close();

FILE *f;

f = fopen(filename, "rb");
if (!f) return false;

ov_open(f, &vf, NULL, 0);

// ok now the tricky part


// the vorbis_info struct keeps the most of the interesting format

// info

vorbis_info *vi = ov_info(&vf,-1);

// set the wave format

WAVEFORMATEX wfm;

memset(&wfm, 0, sizeof(wfm));

wfm.cbSize = sizeof(wfm);
wfm.nChannels = vi->channels;
wfm.wBitsPerSample = 16; // ogg vorbis is always

// 16 bit

wfm.nSamplesPerSec = vi->rate;
wfm.nAvgBytesPerSec = wfm.nSamplesPerSec*wfm.nChannels*2;
wfm.nBlockAlign = 2*wfm.nChannels;
wfm.wFormatTag = 1;


// set up the buffer

DSBUFFERDESC desc;

desc.dwSize = sizeof(desc);
desc.dwFlags = 0;
desc.lpwfxFormat = &wfm;
desc.dwReserved = 0;

desc.dwBufferBytes = BUFSIZE*2;
pDS->CreateSoundBuffer(&desc, &pDSB, NULL );

// fill the buffer


DWORD pos = 0;
int sec = 0;
int ret = 1;
DWORD size = BUFSIZE*2;

char *buf;

pDSB->Lock(0, size, (LPVOID*)&buf, &size, NULL, NULL,
DSBLOCK_ENTIREBUFFER);

// now read in the bits

while(ret && pos<size)
{
ret = ov_read(&vf, buf+pos, size-pos, 0, 2, 1, &sec);
pos += ret;
}

pDSB->Unlock( buf, size, NULL, NULL );

nCurSection =
nLastSection = 0;

return bFileOpened = true;
}

void OggPlayer::Close()
{
bFileOpened = false;

if (pDSB)
pDSB->Release();
}


void OggPlayer::Play(bool loop)
{
if (!bInitialized)
return;

if (!bFileOpened)
return;

// play looping because we will fill the buffer

pDSB->Play(0,0,DSBPLAY_LOOPING);

bLoop = loop;
bDone = false;
bAlmostDone = false;
}

void OggPlayer::Stop()
{
if (!bInitialized)
return;

if (!bFileOpened)
return;

pDSB->Stop();
}

void OggPlayer::Update()
{
DWORD pos;

pDSB->GetCurrentPosition(&pos, NULL);

nCurSection = pos<BUFSIZE?0:1;

// section changed?

if (nCurSection != nLastSection)
{
if (bDone && !bLoop)
Stop();

// gotta use this trick ''cause otherwise there wont be played

// all bits

if (bAlmostDone && !bLoop)
bDone = true;

DWORD size = BUFSIZE;
char *buf;

// fill the section we just left

pDSB->Lock( nLastSection*BUFSIZE, size, (LPVOID*)&buf, &size,
NULL, NULL, 0 );

DWORD pos = 0;
int sec = 0;
int ret = 1;

while(ret && pos<size)
{
ret = ov_read(&vf, buf+pos, size-pos, 0, 2, 1, &sec);
pos += ret;
}

// reached the and?

if (!ret && bLoop)
{
// we are looping so restart from the beginning

// NOTE: sound with sizes smaller than BUFSIZE may be cut

//off


ret = 1;
ov_pcm_seek(&vf, 0);
while(ret && pos<size)
{
ret = ov_read(&vf, buf+pos, size-pos, 0, 2, 1, &sec);
pos += ret;
}
}
else if (!ret && !(bLoop))
{
// not looping so fill the rest with 0

while(pos<size) {
*(buf+pos)=0; pos ++;
}

// and say that after the current section no other sectin

// follows

bAlmostDone = true;
}

pDSB->Unlock( buf, size, NULL, NULL );

nLastSection = nCurSection;
}
}


usage...

OggPlayer *Ogg;
Ogg = new OggPlayer;
Ogg->InitDirectSound(HWND);
Ogg->OpenOgg("Resources/Music/Radoon_NightFlight.ogg");
Ogg->Play(true);

if(Ogg->IsPlaying())
Ogg->Update();

//and if you make it a pointer dont forget to delete it

//i do so with my safedelete template function

SafeDelete(Ogg);




That should do it.

Share this post


Link to post
Share on other sites
I noticed on my machine that, the Update function would crash, if a song wasn''t loaded, i.e. the path was incorrect. I just gotthe code straight from somewhere else, and posted it here. Also i had to switch to multi threded libraries, for the ogg stuff to link. Can you debug, and see what is causing the crash?

Share this post


Link to post
Share on other sites
Well, if I run a debug on the build and have included code for loading an ogg-file, I get a crash in ntdll.dll, and I cannot really debug that file.

If I exclude loading an ogg-file and just set up everything else, then it crashes in update (even though it should not even run that function since I have not loaded a file, and IsPlaying is therefore false).

Share this post


Link to post
Share on other sites
yep that is about the error i got.

i just made sure i opened a file, and that the path was correct, and everything went swell.

maybe i will look over the code, and make sure it doesnt call update.. if no file is loaded.
{edited}

in the constructor change this...

{
bFileOpened = false;
bInitialized = false;
bReleaseDS = false;
pDS = NULL;
pDSB = NULL;
bLoop = false;
bDone = false;
bAlmostDone = false;
}


to this...

{
bFileOpened = false;
bInitialized = false;
bReleaseDS = false;
pDS = NULL;
pDSB = NULL;
bLoop = false;
//change me
bDone = true;
//end change me
bAlmostDone = false;
}


works like a charm, well at least the playing variable returns properly now.

[edited by - justinwalsh on May 11, 2004 3:04:32 PM]

Share this post


Link to post
Share on other sites
Ah, I hope that''ll work (am not home right now), thanks

Though, I am pondering whether the ogg vorbis stuff will work in conjunction with the DirectSound stuff I had set up prior to implementing ov. I use that for playing regular sounds. I am guessing it should not be a problem, or?

Share this post


Link to post
Share on other sites
Okey, at least that solved the update crash, but not the crash I get when I try to load an .ogg file. When I include the line:

Ogg->OpenOgg("music.ogg");

my program crashes in ntdll.dll. I cannot really debug there, all I get when debugging are some strange stuff. I have the file at the specified location (though it should not crash from not finding the file, it should just return). Any ideas?

EDIT: Having narrowed the error down, I found that the function OpenOgg crashed around this line:

ov_open(f, &vf, NULL, 0);

That's pretty weird though.. perhaps I have forgotten something?

[edited by - azjerei on May 14, 2004 6:51:55 AM]

Share this post


Link to post
Share on other sites

  • Advertisement