The whole purpose of DirectMusic is you don't have to explicitly mix the sounds yourself. The default mixing scheme works well enough that I do not need to mess with it. I can write my own mixer but that is sort of going against the design of the API. DirectMusic (even though now deprecated) actually hides the nitty gritty of DirectSound. You can still get to DirectSound through DirectMusic and do your own mixing but I really have no need. Any mixing I might do will probably be as good as or worse than that already being done. Mixing is a cakewalk but effects and so forth are not and require significant amount of DSP knowledge to do correctly which I do not have. If I was going to mix on a low level I would not use DirectSound at all and would instead code a raw mixer based on the Windows multimedia libraries. Aside from the driver level this is about as low level as you can get and I did not think writing something like this was necessary.
The sound thread is running 99% of the time. It is constantly looking at the queue and when the size is > 0 it then sends the ID off to be played. If I use blocking calls then I would need to account for when the queue has more than one sound in it and thus fire off or set the event to unblock. To me this seems less efficient than my current design.
For now blocking calls are a definite 'not going to happen' due to the current design.
I could not attach DXSoundEmitter.h so here it is:
Code:
#pragma once
#include <queue>
#include <vector>
#include "DXAudio.h"
#include "Thread.h"
class DXSoundEmitter:public Thread
{
public:
typedef std::queue<unsigned int> SoundQueue;
typedef std::vector<DXSoundSegment *> SoundVector;
typedef SoundVector::iterator SoundVectorIter;
DXSoundEmitter(void);
virtual ~DXSoundEmitter(void);
static void soundProc(void *obj);
void create(IDirectMusicLoader8 *_Loader,IDirectMusicPerformance8 *_Performance);
void playSound(unsigned int soundID);
unsigned int loadSound(WCHAR *Filename);
bool isPlaying(unsigned int ID);
void setLooping(unsigned int _ID,bool _cond);
void setVolume(unsigned int _ID,int iVolume);
void stopSound(unsigned int ID);
virtual void Loop();
bool allSoundsDone();
private:
SoundQueue m_PlayList;
SoundVector m_Sounds;
IDirectMusicLoader8 *Loader;
IDirectMusicPerformance8 *Performance;
void Play(unsigned int ID,unsigned int _mode = CDX_AUDIO_SECONDARYSEG);
void PlayWithCheck(unsigned int ID,unsigned int _mode = CDX_AUDIO_SECONDARYSEG);
unsigned int m_IDCounter;
CRITICAL_SECTION m_CS;
unsigned int m_PlayingID;
};
The reason for the commented code in DXSoundEmitter::setVolume() is that volume applies to each audiopath and I have not yet designed how I'm going to separate out volumes for various sound objects. I will probably need multiple audiopaths.