This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

 

  Ogg Vorbis Player Class
  Submitted by



This is a simple Ogg Vorbis player class for DirectX 8. Why Ogg Vorbis? Because MP3 is evil ;) You have to pay license royalties to Fraunhofer whenever you code an encoder / decoder. Ogg Vorbis on the other hand is really free. You'll need the Ogg Vorbis Sdk which you can obtained at http://www.vorbis.com/download_win.psp. Link the following files to your project: vorbisfile_static.lib, vorbis_static.lib, ogg_static, dsound.lib. Also be sure your include paths contain the SDK. To use the OggPlayer Class simply do the following:
OggPlayer op;

op.InitDirectSound(hwnd); op.OpenOgg("somemusic.ogg"); op.Play();

while(op.IsPlaying());

op.Close();

You may use this code for whatever you want. :)


Currently browsing [oggplayer.zip] (2,958 bytes) - [OggPlayer.h] - (2,063 bytes)

#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; } };

Currently browsing [oggplayer.zip] (2,958 bytes) - [OggPlayer.cpp] - (4,564 bytes)

#include "oggplayer.h"

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; } }

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

 

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.