- added error checking and allow the game to continue if we cannot init the sound system

- persist error messagebox between program states
This commit is contained in:
Mark Vejvoda
2010-07-09 22:16:26 +00:00
parent eb34eb1fe5
commit f40dd94b1d
10 changed files with 358 additions and 40 deletions

View File

@@ -0,0 +1,135 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Martio Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _SHARED_SOUND_SOUNDPLAYERDS8_H_
#define _SHARED_SOUND_SOUNDPLAYERDS8_H_
#include "sound_player.h"
#include "platform_util.h"
#include <dsound.h>
#include <vector>
using std::vector;
namespace Shared{ namespace Sound{ namespace Ds8{
// =====================================================
// class SoundBuffer
// =====================================================
class SoundBuffer{
protected:
IDirectSoundBuffer8 *dsBuffer;
Sound *sound;
DWORD size;
public:
SoundBuffer();
virtual ~SoundBuffer(){};
virtual void end()=0;
IDirectSoundBuffer8 *getDsBuffer() const {return dsBuffer;}
Sound *getSound() const {return sound;}
void setDsBuffer(IDirectSoundBuffer8 *dsBuffer) {this->dsBuffer= dsBuffer;}
void setSound(IDirectSound8 *dsObject, Sound *sound) {this->sound= sound;}
bool isFree();
bool isReady();
protected:
void createDsBuffer(IDirectSound8 *dsObject);
};
// =====================================================
// class StaticSoundBuffer
// =====================================================
class StaticSoundBuffer: public SoundBuffer{
public:
StaticSound *getStaticSound() const {return static_cast<StaticSound*>(sound);}
void init(IDirectSound8 *dsObject, Sound *sound);
void end();
void play();
private:
void fillDsBuffer();
};
// =====================================================
// class StrSoundBuffer
// =====================================================
class StrSoundBuffer: public SoundBuffer{
private:
enum State{sFree, sFadingOn, sPlaying, sFadingOff, sStopped};
private:
DWORD lastPlayCursor;
State state;
Chrono chrono; //delay-fade chrono
int64 fade; //fade on fade off delay
public:
StrSoundBuffer();
StrSound *getStrSound() const {return static_cast<StrSound*>(sound);}
void init(IDirectSound8 *dsObject, Sound *sound, uint32 strBufferSize);
void end();
void play(int64 fadeOn);
void update();
void stop(int64 fadeOff);
private:
void fillDsBuffer();
void refreshDsBuffer();
void readChunk(void *writePointer, uint32 size);
};
// =====================================================
// class SoundPlayerDs8
//
/// SoundPlayer implementation using Direct Sound 8
// =====================================================
class SoundPlayerDs8: public SoundPlayer{
private:
IDirectSound8 *dsObject;
vector<StaticSoundBuffer> staticSoundBuffers;
vector<StrSoundBuffer> strSoundBuffers;
SoundPlayerParams params;
public:
SoundPlayerDs8();
virtual bool init(const SoundPlayerParams *params);
virtual void end();
virtual void play(StaticSound *staticSound);
virtual void play(StrSound *strSound, int64 fadeOn=0);
virtual void stop(StrSound *strSound, int64 fadeOff=0);
virtual void stopAllSounds();
virtual void updateStreams(); //updates str buffers if needed
private:
bool findStaticBuffer(Sound *sound, int *bufferIndex);
bool findStrBuffer(Sound *sound, int *bufferIndex);
};
// =====================================================
// Misc
// =====================================================
long dsVolume(float floatVolume);
}}}//end namespace
#endif

View File

@@ -91,7 +91,7 @@ class SoundPlayerOpenAL : public SoundPlayer {
public:
SoundPlayerOpenAL();
virtual ~SoundPlayerOpenAL();
virtual void init(const SoundPlayerParams *params);
virtual bool init(const SoundPlayerParams *params);
virtual void end();
virtual void play(StaticSound *staticSound);
virtual void play(StrSound *strSound, int64 fadeOn=0);

View File

@@ -0,0 +1,42 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Martio Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _SHARED_SOUND_SOUNDINTERFACE_H_
#define _SHARED_SOUND_SOUNDINTERFACE_H_
#include "sound_factory.h"
namespace Shared{ namespace Sound{
// =====================================================
// class SoundInterface
// =====================================================
class SoundInterface{
private:
SoundFactory *soundFactory;
private:
SoundInterface() {}
SoundInterface(SoundInterface &);
void operator=(SoundInterface &);
public:
static SoundInterface &getInstance();
void setFactory(SoundFactory *soundFactory);
SoundPlayer *newSoundPlayer();
};
}}//end namespace
#endif

View File

@@ -0,0 +1,63 @@
// ==============================================================
// This file is part of Glest Shared Library (www.glest.org)
//
// Copyright (C) 2001-2008 Martio Figueroa
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
#ifndef _SHARED_SOUND_SOUNDPLAYER_H_
#define _SHARED_SOUND_SOUNDPLAYER_H_
#include "sound.h"
#include "types.h"
using Shared::Platform::uint32;
namespace Shared{ namespace Sound{
// =====================================================
// class SoundPlayerParams
// =====================================================
class SoundPlayerParams{
public:
uint32 strBufferSize;
uint32 strBufferCount;
uint32 staticBufferCount;
SoundPlayerParams();
};
// =====================================================
// class SoundPlayer
//
// Interface that every SoundPlayer will implement
// =====================================================
class SoundPlayer{
protected:
bool initOk;
public:
virtual ~SoundPlayer()
{
initOk = false;
};
virtual bool init(const SoundPlayerParams *params)= 0;
virtual void end()= 0;
virtual void play(StaticSound *staticSound)= 0;
virtual void play(StrSound *strSound, int64 fadeOn=0)= 0; //delay and fade in miliseconds
virtual void stop(StrSound *strSound, int64 fadeOff=0)= 0;
virtual void stopAllSounds()= 0;
virtual void updateStreams()= 0;
virtual bool wasInitOk() const { return initOk; }
};
}}//end namespace
#endif

View File

@@ -335,35 +335,50 @@ void StrSoundBuffer::readChunk(void *writePointer, uint32 size){
SoundPlayerDs8::SoundPlayerDs8(){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
dsObject= NULL;
initOk = false;
}
void SoundPlayerDs8::init(const SoundPlayerParams *params){
bool SoundPlayerDs8::init(const SoundPlayerParams *params){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
initOk = false;
HRESULT hr;
if(params == NULL) {
throw std::runtime_error("params == NULL");
}
this->params= *params;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//reserve memory for buffers
staticSoundBuffers.resize(params->staticBufferCount);
strSoundBuffers.resize(params->strBufferCount);
try {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//reserve memory for buffers
staticSoundBuffers.resize(params->staticBufferCount);
strSoundBuffers.resize(params->strBufferCount);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//create object
hr=DirectSoundCreate8(NULL, &dsObject, NULL);
if (hr!=DS_OK){
throw runtime_error("Can't create direct sound object");
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//create object
hr=DirectSoundCreate8(NULL, &dsObject, NULL);
if (hr!=DS_OK){
throw runtime_error("Can't create direct sound object");
}
//Set cooperative level
hr= dsObject->SetCooperativeLevel(GetActiveWindow(), DSSCL_PRIORITY);
if (hr!=DS_OK){
throw runtime_error("Can't set cooperative level of dsound");
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
//Set cooperative level
hr= dsObject->SetCooperativeLevel(GetActiveWindow(), DSSCL_PRIORITY);
if (hr!=DS_OK){
throw runtime_error("Can't set cooperative level of dsound");
}
initOk = true;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
} catch(const exception &ex) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
return initOk;
}
void SoundPlayerDs8::end(){
@@ -375,6 +390,8 @@ void SoundPlayerDs8::end(){
}
void SoundPlayerDs8::play(StaticSound *staticSound){
if(initOk == false) return;
int bufferIndex= -1;
assert(staticSound!=NULL);
@@ -388,6 +405,7 @@ void SoundPlayerDs8::play(StaticSound *staticSound){
}
void SoundPlayerDs8::play(StrSound *strSound, int64 fadeOn){
if(initOk == false) return;
int bufferIndex= -1;
//play sound if buffer found
@@ -398,6 +416,7 @@ void SoundPlayerDs8::play(StrSound *strSound, int64 fadeOn){
}
void SoundPlayerDs8::stop(StrSound *strSound, int64 fadeOff){
if(initOk == false) return;
//find the buffer with this sound and stop it
for(int i= 0; i<params.strBufferCount; ++i){
if(strSoundBuffers[i].getSound()==strSound){
@@ -407,6 +426,8 @@ void SoundPlayerDs8::stop(StrSound *strSound, int64 fadeOff){
}
void SoundPlayerDs8::stopAllSounds(){
if(initOk == false) return;
for(int i=0; i<params.strBufferCount; ++i){
if(!strSoundBuffers[i].isFree()){
strSoundBuffers[i].stop(0);
@@ -421,6 +442,8 @@ void SoundPlayerDs8::stopAllSounds(){
}
void SoundPlayerDs8::updateStreams(){
if(initOk == false) return;
for(int i=0; i<params.strBufferCount; ++i){
strSoundBuffers[i].update();
}
@@ -430,6 +453,7 @@ void SoundPlayerDs8::updateStreams(){
bool SoundPlayerDs8::findStaticBuffer(Sound *sound, int *bufferIndex){
bool bufferFound= false;
if(initOk == false) return bufferFound;
assert(sound!=NULL);
@@ -470,6 +494,7 @@ bool SoundPlayerDs8::findStaticBuffer(Sound *sound, int *bufferIndex){
bool SoundPlayerDs8::findStrBuffer(Sound *sound, int *bufferIndex){
bool bufferFound= false;
if(initOk == false) return bufferFound;
assert(sound!=NULL);
assert(sound->getVolume()<=1.0f && sound->getVolume()>=0.0f);

View File

@@ -292,6 +292,7 @@ SoundPlayerOpenAL::SoundPlayerOpenAL() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
device = 0;
initOk = false;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
@@ -300,6 +301,7 @@ SoundPlayerOpenAL::~SoundPlayerOpenAL() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
end();
initOk = false;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
@@ -312,18 +314,24 @@ void SoundPlayerOpenAL::printOpenALInfo()
<< "OpenAl Extensions: " << alGetString(AL_RENDERER) << "\n";
}
void SoundPlayerOpenAL::init(const SoundPlayerParams* params) {
bool SoundPlayerOpenAL::init(const SoundPlayerParams* params) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
initOk = false;
if(params == NULL) {
throw std::runtime_error("params == NULL");
}
this->params = *params;
device = alcOpenDevice(0);
if(device == 0) {
printOpenALInfo();
throw std::runtime_error("Couldn't open audio device.");
}
try {
device = alcOpenDevice(0);
if(device == 0) {
printOpenALInfo();
throw std::runtime_error("Couldn't open audio device.");
}
int attributes[] = { 0 };
context = alcCreateContext(device, attributes);
checkAlcError("Couldn't create audio context: ");
@@ -331,13 +339,16 @@ void SoundPlayerOpenAL::init(const SoundPlayerParams* params) {
checkAlcError("Couldn't select audio context: ");
checkAlError("Audio error after init: ");
} catch(...) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
initOk = true;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
} catch(const exception &ex) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
printOpenALInfo();
throw;
//throw std::runtime_error(ex.what());
}
return initOk;
}
void SoundPlayerOpenAL::end() {
@@ -389,6 +400,7 @@ void SoundPlayerOpenAL::end() {
if(device != 0) {
alcCloseDevice(device);
device = 0;
initOk = false;
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
@@ -397,6 +409,8 @@ void SoundPlayerOpenAL::end() {
void SoundPlayerOpenAL::play(StaticSound* staticSound) {
assert(staticSound != 0);
if(initOk == false) return;
try {
StaticSoundSource* source = findStaticSoundSource();
if(source == 0)
@@ -410,6 +424,8 @@ void SoundPlayerOpenAL::play(StaticSound* staticSound) {
void SoundPlayerOpenAL::play(StrSound* strSound, int64 fadeOn) {
assert(strSound != 0);
if(initOk == false) return;
try {
StreamSoundSource* source = findStreamSoundSource();
source->play(strSound, fadeOn);
@@ -421,6 +437,8 @@ void SoundPlayerOpenAL::play(StrSound* strSound, int64 fadeOn) {
void SoundPlayerOpenAL::stop(StrSound* strSound, int64 fadeOff) {
assert(strSound != 0);
if(initOk == false) return;
for(StreamSoundSources::iterator i = streamSources.begin();
i != streamSources.end(); ++i) {
StreamSoundSource* source = *i;
@@ -431,6 +449,8 @@ void SoundPlayerOpenAL::stop(StrSound* strSound, int64 fadeOff) {
}
void SoundPlayerOpenAL::stopAllSounds() {
if(initOk == false) return;
for(StaticSoundSources::iterator i = staticSources.begin();
i != staticSources.end(); ++i) {
StaticSoundSource* source = *i;
@@ -444,6 +464,8 @@ void SoundPlayerOpenAL::stopAllSounds() {
}
void SoundPlayerOpenAL::updateStreams() {
if(initOk == false) return;
assert(context != 0);
try {
for(StreamSoundSources::iterator i = streamSources.begin();
@@ -465,6 +487,8 @@ void SoundPlayerOpenAL::updateStreams() {
}
StaticSoundSource* SoundPlayerOpenAL::findStaticSoundSource() {
if(initOk == false) return NULL;
// try to find a stopped source
for(StaticSoundSources::iterator i = staticSources.begin();
i != staticSources.end(); ++i) {
@@ -490,6 +514,8 @@ StaticSoundSource* SoundPlayerOpenAL::findStaticSoundSource() {
}
StreamSoundSource* SoundPlayerOpenAL::findStreamSoundSource() {
if(initOk == false) return NULL;
// try to find a stopped source
for(StreamSoundSources::iterator i = streamSources.begin();
i != streamSources.end(); ++i) {
@@ -514,8 +540,7 @@ StreamSoundSource* SoundPlayerOpenAL::findStreamSoundSource() {
return source;
}
void SoundPlayerOpenAL::checkAlcError(const char* message)
{
void SoundPlayerOpenAL::checkAlcError(const char* message) {
int err = alcGetError(device);
if(err != ALC_NO_ERROR) {
std::stringstream msg;
@@ -524,8 +549,7 @@ void SoundPlayerOpenAL::checkAlcError(const char* message)
}
}
void SoundPlayerOpenAL::checkAlError(const char* message)
{
void SoundPlayerOpenAL::checkAlError(const char* message) {
int err = alGetError();
if(err != AL_NO_ERROR) {
std::stringstream msg;