Using DirectSound and OggVorbis

Started by
6 comments, last by azjerei 19 years, 11 months ago
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.
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 lengthclass 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 functionSafeDelete(Ogg);



That should do it.
Hrmm.. too bad I get a crash in NTDLL.dll when I use this code..
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?
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).
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]
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?
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]

This topic is closed to new replies.

Advertisement