Code on this page show.
How to create and manage sounds in your own game app’s.
Using DirectX 7.
Simple sample how to use it.
1) some were in your code
#include "sdisoundobject.h"
sdisound* sob;//only one object can be exist
try{
if((sob=new sdisound)==NULL)throw(false);
if FAILED(sob->Create(true)) //support 3dsound
{
if FAILED(sob->Create(false))//not support 3dsound keep trying
throw(false);
}
……………
}
catch(bool /*tr*/)
{
init failed exit or else procceed your gerror
you havn’t sound
}
…………
2) some were in your code
sdisoundobject* lsob=NULL;
sdisoundob*sob1=NULL;
try{
if((lsob=new sdisoundobject(sob))==NULL)throw(false);
if(!lsob->Create(3))throw(false);
//3 = num of sounds
sob1=lsob->SDI_AddSound(0,“explode1.wav”,false);
lsob->SDI_AddSound(1,“explode2.wav”,false);
lsob->SDI_AddSound(2,“explode3.wav”,false);
//you must check return value to detect error
}
catch(bool /*tr*/)
{
procceed your gerror
}
3) some were in your code
sob1->Play(true);//loop playing
lsob-> SDI_PlaySound(1,true);//loop playing
lsob-> SDI_PlaySound(2,false);//onse playing
…………
//======================================================//
Sdisound main class of sound device that manage initialization
#ifndef SDISOUNDAPPCLASS_H
#define SDISOUNDAPPCLASS_H
#include "D3DUtil.h"
#include "sdisoundguids.h"
class sdisound
{
public:
sdisound();
~sdisound();
HRESULT Create(bool suport3dsound);
bool SDI_SetListenPos(D3DVECTOR tpos,bool imediatly);
bool SDI_GetListenPos(D3DVECTOR&tpos);
bool SDI_SetListenDir(D3DVECTOR tdir,bool imediatly);
bool SDI_GetListenDir(D3DVECTOR&tdir);
LPDIRECTSOUND SDI_GetDS(){return m_DS;}
LPDIRECTSOUND3DLISTENER SDI_Get3DL(){return m_Listener;}
private:
void Destroy(void);
bool SDI_SoundInit(bool suport3dsound);
void SDI_SoundUnInit();
bool SDI_MakeIt3D(bool suport3dsound);
bool SDI_DSEnum(DWORD flags);
bool m_activated;
bool m_lis;//
sdisguids m_g;
LPDIRECTSOUNDBUFFER m_PDSBuffer;//primery buffer
LPDIRECTSOUND m_DS;//direct sound
LPDIRECTSOUND3DLISTENER m_Listener;//listener
};
#endif
#include "sdisoundappclass.h"
#include "sdiglobvars.h"
extern sdi_GV g_sys_var;
sdisound::
sdisound()
{
m_activated=false;
m_lis=false;
m_Listener=NULL;
m_PDSBuffer=NULL;
m_DS=NULL;
}
sdisound::
~sdisound()
{
Destroy();
}
HRESULT sdisound::
Create(bool suport3dsound)
{
if(m_activated)return DS_OK;
m_activated=SDI_SoundInit(suport3dsound);
if(m_activated==true)return DS_OK;
return E_FAIL;
}
void sdisound::
Destroy(void)
{
if(m_activated)SDI_SoundUnInit();
}
bool sdisound::
SDI_SetListenPos(D3DVECTOR tpos,bool imediatly)
{
HRESULT hr;
DWORD dwApply;
if(!m_activated||!m_lis)return false;
if(imediatly){dwApply=DS3D_IMMEDIATE;}
else{dwApply=DS3D_DEFERRED;}
hr=m_Listener->SetPosition(tpos.x,
tpos.y,
tpos.z,
dwApply);
if FAILED(hr)return false;
return true;
}
bool sdisound::
SDI_GetListenPos(D3DVECTOR&tpos)
{
HRESULT hr;
if(!m_activated||!m_lis)return false;
hr=m_Listener->GetPosition(&tpos);
if FAILED(hr)return false;
return true;
}
bool sdisound::
SDI_SetListenDir(D3DVECTOR tdir,bool imediatly)
{
HRESULT hr;
DWORD dwApply;
if(!m_activated||!m_Listener)return false;
if(imediatly){dwApply=DS3D_IMMEDIATE;}
else{dwApply=DS3D_DEFERRED;}
hr=m_Listener->
SetOrientation(tdir.x,
tdir.y,
tdir.z,
0.0,
1.0f,
0.0,
dwApply);
if FAILED(hr)return false;
return true;
}
bool sdisound::
SDI_GetListenDir(D3DVECTOR&tdir)
{
HRESULT hr;
D3DVECTOR tdiru;
if(!m_activated||!m_Listener)return false;
hr=m_Listener->
GetOrientation(&tdir,
&tdiru);
if FAILED(hr)return false;
return true;
}
bool sdisound::
SDI_SoundInit(bool suport3dsound)
{
DSBUFFERDESC dsbd;
WAVEFORMATEX wfx;
HRESULT hr;
bool mgtr;
LPGUID tg=NULL;
//try get beter guid
// try detetect hardw sound card 2 chanels 22khz
mgtr=m_g.Create(true,2,22050);
if(mgtr)tg=m_g.SDI_GetBeter();
//Creating directsound
hr=DirectSoundCreate(tg,&m_DS,NULL);
if FAILED(hr)return false;
// Set coop level priority
hr=m_DS->
SetCooperativeLevel(g_sys_var.m_hwnd,
DSSCL_PRIORITY);
if FAILED(hr)return false;
// primary buffer options
ZeroMemory(&dsbd,sizeof(DSBUFFERDESC));
dsbd.dwSize=sizeof(DSBUFFERDESC);
dsbd.dwFlags=DSBCAPS_CTRLVOLUME|
DSBCAPS_PRIMARYBUFFER;
// Set prymery buffer to 22Khz 16-bit output format
ZeroMemory(&wfx,sizeof(WAVEFORMATEX));
wfx.wFormatTag=WAVE_FORMAT_PCM;
wfx.nChannels=2;
wfx.nSamplesPerSec=22050;
wfx.wBitsPerSample=16;
wfx.nBlockAlign=wfx.wBitsPerSample/8*wfx.nChannels;
wfx.nAvgBytesPerSec=wfx.nSamplesPerSec*wfx.nBlockAlign;
if(suport3dsound)
dsbd.dwFlags|=DSBCAPS_CTRL3D|
DSBCAPS_LOCSOFTWARE;
hr=m_DS->
CreateSoundBuffer(&dsbd,
&m_PDSBuffer,
NULL);
if FAILED(hr)return false;
//set formatex
hr=m_PDSBuffer->SetFormat(&wfx);
if FAILED(hr)return false;
// Get listener interface
m_lis=SDI_MakeIt3D(suport3dsound);
return true;
}
bool sdisound::
SDI_MakeIt3D(bool suport3dsound)
{
HRESULT hr;
if(suport3dsound)
{
hr=m_PDSBuffer->
QueryInterface(IID_IDirectSound3DListener,
(LPVOID *)&m_Listener);
if FAILED(hr)
return false;
else
return true;
}
return true;
}
void sdisound::
SDI_SoundUnInit(void)
{
// very urgent!!!!
// before this all sound buffers
// must be stoped and released
SAFE_RELEASE(m_Listener);
m_lis=false;
SAFE_RELEASE(m_PDSBuffer);
SAFE_RELEASE(m_DS);
m_activated=false;
}
#ifndef SDISOUNDGUIDS_H
#define SDISOUNDGUIDS_H
#include <dsound.h>
class sdisguids
{
public:
sdisguids();
~sdisguids();
bool Create(bool hardw,int numch,int bitsps);
bool SDI_Record(const char*desc,const char*mod,LPGUID guid);
LPGUID SDI_GetBeter();
LPGUID SDI_GetById(int Id);
int SDI_GetMaxDetected();
private:
void Destroy();
bool SDI_EnumDSG(bool hardw,int numch,int bitsps);
char**m_desc;
char**m_module;
LPGUID* m_guids;
int m_beter;
int m_curent;
int m_detected;
bool m_ok;
};
#endif
#include "sdisoundguids.h"
#include "d3dutil.h"
#define SDIMAXGUIDSDETECT 5
BOOL CALLBACK SDI_DSEnumCallback(LPGUID lpGuid,
LPCSTR lpcstrDescription,
LPCSTR lpcstrModule,
LPVOID lpContext)
{
static bool lr=true;
sdisguids*tcg=(sdisguids*)lpContext;
if(lr)
lr=tcg->SDI_Record(lpcstrDescription,
lpcstrModule,
lpGuid);
return true;
}
sdisguids::
sdisguids()
{
m_desc=NULL;
m_module=NULL;
m_guids=NULL;
m_beter=0;
m_curent=0;
m_detected=0;
m_ok=false;
}
sdisguids::
~sdisguids()
{
Destroy();
m_ok=false;
}
bool sdisguids::
Create(bool hardw,int numch,int bitsps)
{
int i;
m_desc=new char*[SDIMAXGUIDSDETECT];
m_module=new char*[SDIMAXGUIDSDETECT];
m_guids=new LPGUID[SDIMAXGUIDSDETECT];
if(!m_desc||
!m_module||
!m_guids)
{
SAFE_DELETE(m_desc);
SAFE_DELETE(m_module);
SAFE_DELETE(m_guids);
return false;
}
m_ok=true;
for(i=0;i<SDIMAXGUIDSDETECT;i++)
{
m_desc[i]=NULL;
m_module[i]=NULL;
m_guids[i]=NULL;
}
return SDI_EnumDSG(hardw,numch,bitsps);
}
LPGUID sdisguids::
SDI_GetBeter()
{
if(m_detected&&m_ok)return m_guids[m_beter];
return NULL;
}
LPGUID sdisguids::
SDI_GetById(int Id)
{
if(m_ok&&m_detected&&(Id>=0&&Id<SDIMAXGUIDSDETECT))
return m_guids[Id];
return NULL;
}
int sdisguids::
SDI_GetMaxDetected()
{
return m_detected;
}
void sdisguids::
Destroy()
{
int i;
if(m_ok)
{
for(i=0;i<SDIMAXGUIDSDETECT;i++)
{
SAFE_DELETE(m_desc[i]);
SAFE_DELETE(m_module[i]);
}
SAFE_DELETE(m_desc);
SAFE_DELETE(m_module);
SAFE_DELETE(m_guids);
}
}
bool sdisguids::
SDI_Record(const char*desc,const char*mod,LPGUID guid)
{
if(m_o)
{
if(m_curent<SDIMAXGUIDSDETECT)
{
if(m_guids[m_curent])return false;
SAFE_DELETE(m_desc[m_curent]);
SAFE_DELETE(m_module[m_curent]);
m_desc[m_curent]=new char[strlen(desc)+1];
m_module[m_curent]=new char[strlen(mod)+1];
if(!m_module[m_curent]||!m_desc[m_curent])
{
SAFE_DELETE(m_desc[m_curent]);
SAFE_DELETE(m_module[m_curent]);
return false;
}
strcpy(m_desc[m_curent],desc);
strcpy(m_module[m_curent],mod);
m_guids[m_curent]=guid;
m_detected++;
m_curent++;
return true;
}
}
return false;
}
bool sdisguids::
SDI_EnumDSG(bool hardw,int numch,int bitsps)
{
HRESULT hr;
hr=DirectSoundEnumerate(SDI_DSEnumCallback,this);
if FAILED(hr)return false;
m_curent=0;
m_beter=0;
//serch for beter
return true;
}
#ifndef SDISOUNDOBJECT_H
#define SDISOUNDOBJECT_H
#include "sdisoundappclass.h"
class sdisoundob
{
public:
sdisoundob();
~sdisoundob();
bool Create(LPDIRECTSOUND ds,
char*wavfilename,
bool is3dbuff,
bool hedrelative);
void SDI_Play(bool loop);
void SDI_Stop();
bool SDI_SetPos(D3DVECTOR tpos,
bool imediatly);
bool SDI_GetPos(D3DVECTOR&tpos);
bool SDI_SetVolv(long nvol);
bool SDI_SetVolb(bool crease);
bool SDI_SetPan(long npan);
private:
void Destroy();
bool SDI_MakeIt3D(bool hedrelative);
bool SDI_Load(LPDIRECTSOUND ds,
char*wavfilename,
bool is3dbuff);
LPDIRECTSOUNDBUFFER m_buffer;//LPDIRECTSOUNDBUFFER
LPDIRECTSOUND3DBUFFER m_buffer3d;//3d buffer
bool m_is3d;
bool m_loadedOK;
};
class sdisoundobject
{
public:
sdisoundobject(sdisound* tse);
~sdisoundobject();
bool Create(int numofsoundstobecreated);
sdisoundob* SDI_AddSound(int tId,
char*wavfilename,
bool is3dbuff);
void Destroy(int tId);
void SDI_PlaySound(int tId,bool loopyesno);
void SDI_StopSound(int tId);
bool SDI_SetPosition(int tId,
D3DVECTOR tpos,
bool imediatly);
bool SDI_SetDirection(int tId,
D3DVECTOR tdir,
bool imediatly);
private:
void Destroy();
sdisound* se;
sdisoundob **objectsounds;
bool*soundsloadedok;
int maxsoundstoload;
};
#endif
#include "sdisoundobject.h"
#include <mmsystem.h>
sdisoundob::sdisoundob()
{
m_buffer=NULL;
m_buffer3d=NULL;
m_is3d=false;
m_loadedOK=false;
}
sdisoundob::~sdisoundob()
{
Destroy();
}
bool sdisoundob::
Create(LPDIRECTSOUND ds,
char*wavfilename,
bool is3dbuff,
bool hedrelative)
{
if(m_loadedOK)return false;
m_loadedOK=SDI_Load(ds,wavfilename,is3dbuff);
if(m_loadedOK&&is3dbuff)
m_is3d=SDI_MakeIt3D(hedrelative);
return m_loadedOK;
}
void sdisoundob::
Destroy()
{
SDI_Stop();
SAFE_RELEASE(m_buffer);
SAFE_RELEASE(m_buffer3d);
m_is3d=false;
m_loadedOK=false;
}
void sdisoundob::
SDI_Play(bool loop)
{
unsigned long res;
if(!m_loadedOK)return;
m_buffer->GetStatus(&res);
if(res!=DSBSTATUS_PLAYING||
res!=DSBSTATUS_LOOPING)
{
if(loop==true)
m_buffer->Play(0,0,DSBPLAY_LOOPING);
else
m_buffer->Play(0, 0, 0);
}
}
void sdisoundob::
SDI_Stop()
{
unsigned long res;
if(!m_loadedOK)return;
m_buffer->GetStatus(&res);
if(res==DSBSTATUS_PLAYING||
res==DSBSTATUS_LOOPING)
m_buffer->Stop();
}
bool sdisoundob::
SDI_SetPos(D3DVECTOR tpos,
bool imediatly)
{
HRESULT hr;
if(!m_loadedOK&&!m_is3d)return false;
hr=m_buffer3d->
SetPosition(tpos.x,
tpos.y,
tpos.z,
DS3D_IMMEDIATE);
if FAILED(hr)return false;
return true;
}
bool sdisoundob::
SDI_GetPos(D3DVECTOR&tpos)
{
HRESULT hr;
if(!m_loadedOK&&!m_is3d)return false;
hr=m_buffer3d->GetPosition(&tpos);
if FAILED(hr)return false;
return true;
}
bool sdisoundob::
SDI_SetVolv(long nvol)
{
HRESULT hr;
if(!m_loadedOK)return false;
hr=m_buffer->SetVolume(nvol);
if FAILED(hr)return false;
return true;
}
bool sdisoundob::
SDI_SetVolb(bool crease)
{
HRESULT hr;
long tvol;
if(!m_loadedOK)return false;
hr=m_buffer->GetVolume(&tvol);
if FAILED(hr)return false;
if(crease)
tvol=+10;
else
tvol=-10;
return SDI_SetVolv(tvol);
}
bool sdisoundob::
SDI_SetPan(long npan)
{
HRESULT hr;
if(!m_loadedOK)return false;
hr=m_buffer->SetPan(npan);
if FAILED(hr)return false;
return true;
}
bool sdisoundob::
SDI_Load(LPDIRECTSOUND ds,
char*wavfilename,
bool is3dbuff)
{
// Thanks to Omar Santiago who wrote
// functional part of this function.
HMMIO wavefile;
MMCKINFO parent,child;
WAVEFORMATEX wavefmt;
DSBUFFERDESC bufdesc;
void *write1=0,*write2=0;
unsigned long length1,length2;
HRESULT hr;
//Open a wav file
wavefile=mmioOpen(wavfilename,
0,
MMIO_READ|MMIO_ALLOCBUF);
if(wavefile==NULL)return false;
//Find wave data
memset(&parent,0,sizeof(MMCKINFO));
parent.fccType=mmioFOURCC('W','A','V','E');
mmioDescend(wavefile, &parent, 0, MMIO_FINDRIFF);
//Find fmt data
memset(&child,0,sizeof(MMCKINFO));
child.fccType=mmioFOURCC('f','m','t',' ');
mmioDescend(wavefile,&child,&parent,0);
//Read the format
mmioRead(wavefile,(char*)&wavefmt,sizeof(wavefmt));
if(wavefmt.wFormatTag!=WAVE_FORMAT_PCM)return false;
mmioAscend(wavefile,&child,0);
//Find the wave data chunk
child.ckid=mmioFOURCC('d','a','t','a');
mmioDescend(wavefile,&child,&parent,MMIO_FINDCHUNK);
//Create a DirectSoundBuffer to hold the wave data
memset(&bufdesc,0,sizeof(DSBUFFERDESC));
bufdesc.dwSize=sizeof(DSBUFFERDESC);
bufdesc.dwFlags=DSBCAPS_STATIC|
DSBCAPS_CTRLVOLUME|
DSBCAPS_CTRLPAN;
if(is3dbuff)
bufdesc.dwFlags|=DSBCAPS_CTRL3D|
DSBCAPS_MUTE3DATMAXDISTANCE;
bufdesc.dwBufferBytes=child.cksize;
bufdesc.lpwfxFormat=&wavefmt;
hr=ds->CreateSoundBuffer(&bufdesc,&m_buffer,NULL);
if FAILED(hr)return false;
// Write the wave data to DirectSoundBuffer you
// just created
m_buffer->Lock(0,child.cksize,&write1,&length1,&write2,&length2,0);
if(write1>0)mmioRead(wavefile,(char*)write1,length1);
if(write2>0)mmioRead(wavefile,(char*)write2,length2);
m_buffer->Unlock(write1,length1,write2,length2);
//Close the wavefile
mmioClose(wavefile, 0);
//making def setings volume and pan
m_buffer->SetVolume(DSBVOLUME_MAX);
m_buffer->SetPan(DSBPAN_CENTER);
return true;
}
bool sdisoundob::
SDI_MakeIt3D(bool hedrelative)
{
HRESULT hr;
DWORD s3dmf;
hr=m_buffer->
QueryInterface(IID_IDirectSound3DBuffer,
(LPVOID *)&m_buffer3d);
if SUCCEEDED(hr)
{
if(hedrelative)
s3dmf=DS3DMODE_HEADRELATIVE;
else
s3dmf=DS3DMODE_NORMAL;
// Set 3-D parameters of this sound.
m_buffer3d->SetMode(s3dmf,
DS3D_IMMEDIATE);
m_buffer3d->SetMaxDistance(DS3D_DEFAULTMAXDISTANCE,
DS3D_IMMEDIATE);
m_buffer3d->SetMinDistance(DS3D_DEFAULTMINDISTANCE,
DS3D_IMMEDIATE);
return true;
}
SAFE_RELEASE(m_buffer3d);
return false;
}
#include "sdisoundobject.h"
#define MAXSOUNDOBJECTS 100
//===================================//
sdisoundobject::
sdisoundobject(sdisound* tse)
{
objectsounds=NULL;
se=tse;
soundsloadedok=NULL;
maxsoundstoload=0;
}
sdisoundobject::
~sdisoundobject()
{
Destroy();
}
bool sdisoundobject::
Create(int numofsoundstobecreated)
{
int i;
if(se==NULL||
numofsoundstobecreated<1||
numofsoundstobecreated>MAXSOUNDOBJECTS)
return false;
soundsloadedok=new bool[numofsoundstobecreated];
objectsounds=new sdisoundob*[numofsoundstobecreated];
if(soundsloadedok==NULL||
objectsounds==NULL)
{
SAFE_DELETE(soundsloadedok);
SAFE_DELETE(objectsounds);
return false;
}
maxsoundstoload=numofsoundstobecreated;
for(i=0;i<maxsoundstoload;i++)
{
objectsounds[i]=NULL;
soundsloadedok[i]=false;
}
return true;
}
sdisoundob* sdisoundobject::
SDI_AddSound(int tId,
char*wavfilename,
bool is3dbuff)
{
bool t3ds=false;
if(tId<0||tId>=maxsoundstoload)return NULL;
if(soundsloadedok[tId]==true)return NULL;
if((objectsounds[tId]=new sdisoundob)==NULL)
// so do not try to loadthis wav
return NULL;
// load wav and set soundsloadedok true or false
if(is3dbuff&&NULL!=se->SDI_Get3DL())t3ds=true;
if(objectsounds[tId]->Create(se->SDI_GetDS(),
wavfilename,
t3ds,
false))
{
soundsloadedok[tId]=true;
return objectsounds[tId];
}
SAFE_DELETE(objectsounds[tId]);
return NULL;
}
void sdisoundobject::
Destroy()
{
int i;
if(maxsoundstoload>0)
{
for(i=0;i<maxsoundstoload;i++)
{
SAFE_DELETE(objectsounds[i]);
}
SAFE_DELETE(objectsounds);
SAFE_DELETE(soundsloadedok);
}
maxsoundstoload=0;
}
void sdisoundobject::
Destroy(int tId)
{
if(tId<0||tId>=maxsoundstoload)return;
if(soundsloadedok[tId]==false)return;
SAFE_DELETE(objectsounds[tId]);
soundsloadedok[tId]=false;
}
void sdisoundobject::
SDI_PlaySound(int tId,
bool loopyesno)
{
if(!soundsloadedok[tId]||
tId<0||
tId>=maxsoundstoload)return;
objectsounds[tId]->SDI_Play(loopyesno);
}
void sdisoundobject::
SDI_StopSound(int tId)
{
if(!soundsloadedok[tId]||
tId<0||
tId>=maxsoundstoload)return;
objectsounds[tId]->SDI_Stop();
}
bool sdisoundobject::
SDI_SetPosition(int tId,
D3DVECTOR tpos,
bool imediatly)
{
if(!soundsloadedok[tId]||
tId<0||
tId>=maxsoundstoload)return false;
return objectsounds[tId]->SDI_SetPos(tpos,imediatly);
}