[Orxonox-commit 1604] r6322 - code/branches/presentation2/src/orxonox/sound
rgrieder at orxonox.net
rgrieder at orxonox.net
Fri Dec 11 14:15:43 CET 2009
Author: rgrieder
Date: 2009-12-11 14:15:43 +0100 (Fri, 11 Dec 2009)
New Revision: 6322
Modified:
code/branches/presentation2/src/orxonox/sound/AmbientSound.cc
code/branches/presentation2/src/orxonox/sound/AmbientSound.h
code/branches/presentation2/src/orxonox/sound/BaseSound.cc
code/branches/presentation2/src/orxonox/sound/BaseSound.h
code/branches/presentation2/src/orxonox/sound/SoundManager.cc
code/branches/presentation2/src/orxonox/sound/SoundManager.h
code/branches/presentation2/src/orxonox/sound/WorldSound.cc
code/branches/presentation2/src/orxonox/sound/WorldSound.h
Log:
Added audio source management. This should reduce the problems when loading too many sounds.
However if there are too many players shooting at the same time, some sounds may still not play.
Modified: code/branches/presentation2/src/orxonox/sound/AmbientSound.cc
===================================================================
--- code/branches/presentation2/src/orxonox/sound/AmbientSound.cc 2009-12-11 01:05:58 UTC (rev 6321)
+++ code/branches/presentation2/src/orxonox/sound/AmbientSound.cc 2009-12-11 13:15:43 UTC (rev 6322)
@@ -118,6 +118,7 @@
float AmbientSound::getVolumeGain()
{
+ assert(GameMode::playsSound());
return SoundManager::getInstance().getVolume(SoundType::ambient);
}
Modified: code/branches/presentation2/src/orxonox/sound/AmbientSound.h
===================================================================
--- code/branches/presentation2/src/orxonox/sound/AmbientSound.h 2009-12-11 01:05:58 UTC (rev 6321)
+++ code/branches/presentation2/src/orxonox/sound/AmbientSound.h 2009-12-11 13:15:43 UTC (rev 6322)
@@ -49,19 +49,19 @@
public:
AmbientSound(BaseObject* creator);
- virtual ~AmbientSound();
+ ~AmbientSound();
- virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
- virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
- virtual void changedActivity();
+ void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+ void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
+ void changedActivity();
- virtual void play();
- virtual void stop();
- virtual void pause();
+ void play();
+ void stop();
+ void pause();
- virtual float getVolumeGain();
+ float getVolumeGain();
- virtual void setAmbientSource(const std::string& source);
+ void setAmbientSource(const std::string& source);
const std::string& getAmbientSource() const { return this->ambientSource_; }
inline void ambientSourceChanged(){ this->setAmbientSource(this->ambientSource_); }
Modified: code/branches/presentation2/src/orxonox/sound/BaseSound.cc
===================================================================
--- code/branches/presentation2/src/orxonox/sound/BaseSound.cc 2009-12-11 01:05:58 UTC (rev 6321)
+++ code/branches/presentation2/src/orxonox/sound/BaseSound.cc 2009-12-11 13:15:43 UTC (rev 6322)
@@ -42,8 +42,7 @@
namespace orxonox
{
BaseSound::BaseSound()
- : audioSource_(0)
- , bPooling_(false)
+ : bPooling_(false)
, volume_(1.0)
, bLooping_(false)
, state_(Stopped)
@@ -51,25 +50,15 @@
{
RegisterRootObject(BaseSound);
- if (GameMode::playsSound())
- {
- alGenSources(1, &this->audioSource_);
- if (!alIsSource(this->audioSource_))
- COUT(1) << "Sound: Source generation failed: " << SoundManager::getALErrorString(alGetError()) << std::endl;
-
- if (alIsSource(this->audioSource_))
- {
- alSourcei(this->audioSource_, AL_REFERENCE_DISTANCE, 20);
- alSourcei(this->audioSource_, AL_MAX_DISTANCE, 10000);
- }
- }
+ // Initialise audioSource_ to a value that is not a source
+ // 0 is unfortunately not guaranteed to be no source ID.
+ this->audioSource_ = 123456789;
+ while (alIsSource(++this->audioSource_));
}
BaseSound::~BaseSound()
{
- this->setSource(std::string());
- if (GameMode::playsSound() && alIsSource(this->audioSource_))
- alDeleteSources(1, &this->audioSource_);
+ this->stop();
}
void BaseSound::XMLPortExtern(Element& xmlelement, XMLPort::Mode mode)
@@ -83,20 +72,34 @@
void BaseSound::play()
{
this->state_ = Playing;
- if (GameMode::playsSound() && alIsSource(this->audioSource_) && this->getSourceState() != AL_PLAYING)
+ if (GameMode::playsSound() && this->getSourceState() != AL_PLAYING && this->soundBuffer_ != NULL)
{
+ if (!alIsSource(this->audioSource_))
+ this->audioSource_ = SoundManager::getInstance().getSoundSource();
+ if (!alIsSource(this->audioSource_))
+ return;
+ this->initialiseSource();
+
alSourcePlay(this->audioSource_);
-
if (int error = alGetError())
- COUT(2) << "Sound: Error playing sound: " << error << std::endl;
+ COUT(2) << "Sound: Error playing sound: " << SoundManager::getALErrorString(error) << std::endl;
}
}
void BaseSound::stop()
{
this->state_ = Stopped;
- if (GameMode::playsSound() && alIsSource(this->audioSource_))
+ if (alIsSource(this->audioSource_))
+ {
alSourceStop(this->audioSource_);
+ // Release buffer
+ alSourcei(this->audioSource_, AL_BUFFER, AL_NONE);
+ // Release source again
+ SoundManager::getInstance().releaseSoundSource(this->audioSource_);
+ // Get a no source ID
+ this->audioSource_ += 123455;
+ while (alIsSource(++this->audioSource_));
+ }
}
void BaseSound::pause()
@@ -104,13 +107,13 @@
if (this->isStopped())
return;
this->state_ = Paused;
- if (GameMode::playsSound() && alIsSource(this->audioSource_))
+ if (alIsSource(this->audioSource_))
alSourcePause(this->audioSource_);
}
ALint BaseSound::getSourceState() const
{
- if (GameMode::playsSound() && alIsSource(this->audioSource_))
+ if (alIsSource(this->audioSource_))
{
ALint state;
alGetSourcei(this->audioSource_, AL_SOURCE_STATE, &state);
@@ -120,6 +123,25 @@
return AL_INITIAL;
}
+ void BaseSound::initialiseSource()
+ {
+ this->updateVolume();
+ this->setPitch(this->getPitch());
+ this->setLooping(this->getLooping());
+ alSource3f(this->audioSource_, AL_POSITION, 0, 0, 0);
+ alSource3f(this->audioSource_, AL_VELOCITY, 0, 0, 0);
+ alSource3f(this->audioSource_, AL_DIRECTION, 0, 0, 0);
+ alSourcei(this->audioSource_, AL_REFERENCE_DISTANCE, 20);
+ alSourcei(this->audioSource_, AL_MAX_DISTANCE, 10000);
+ if (ALint error = alGetError())
+ COUT(2) << "Sound Warning: Setting source parameters to 0 failed: "
+ << SoundManager::getALErrorString(error) << std::endl;
+ assert(this->soundBuffer_ != NULL);
+ alSourcei(this->audioSource_, AL_BUFFER, this->soundBuffer_->getBuffer());
+ if (ALuint error = alGetError())
+ COUT(1) << "Sound Error: Could not set buffer \"" << this->source_ << "\": " << SoundManager::getALErrorString(error) << std::endl;
+ }
+
void BaseSound::setVolume(float vol)
{
if (vol > 1 || vol < 0)
@@ -135,6 +157,7 @@
float BaseSound::getVolumeGain()
{
+ assert(GameMode::playsSound());
return SoundManager::getInstance().getVolume(SoundType::none);
}
@@ -142,16 +165,18 @@
{
if (alIsSource(this->audioSource_))
{
- alSourcef(this->audioSource_, AL_GAIN, this->volume_*this->getVolumeGain());
+ float volume = this->volume_ * this->getVolumeGain();
+ alSourcef(this->audioSource_, AL_GAIN, volume);
if (int error = alGetError())
- COUT(2) << "Sound: Error setting volume: " << error << std::endl;
+ COUT(2) << "Sound: Error setting volume to " << volume
+ << ": " << SoundManager::getALErrorString(error) << std::endl;
}
}
void BaseSound::setLooping(bool val)
{
this->bLooping_ = val;
- if (GameMode::playsSound() && alIsSource(this->audioSource_))
+ if (alIsSource(this->audioSource_))
alSourcei(this->audioSource_, AL_LOOPING, (val ? AL_TRUE : AL_FALSE));
}
@@ -164,10 +189,10 @@
pitch = pitch < 0.5 ? 0.5 : pitch;
}
this->pitch_ = pitch;
- if (GameMode::playsSound() && alIsSource(this->audioSource_))
+ if (alIsSource(this->audioSource_))
{
if (int error = alGetError())
- COUT(2) << "Sound: Error setting pitch: " << error << std::endl;
+ COUT(2) << "Sound: Error setting pitch: " << SoundManager::getALErrorString(error) << std::endl;
alSourcef(this->audioSource_, AL_PITCH, pitch);
}
}
@@ -182,43 +207,42 @@
if (this->soundBuffer_ != NULL)
{
+ // Stopping is imperative here!
if (alIsSource(this->audioSource_))
{
alSourceStop(this->audioSource_);
- // Unload old buffer first
- alSourcei(this->audioSource_, AL_BUFFER, 0);
+ alSourcei(this->audioSource_, AL_BUFFER, AL_NONE);
}
SoundManager::getInstance().releaseSoundBuffer(this->soundBuffer_, this->bPooling_);
this->soundBuffer_.reset();
}
this->source_ = source;
- if (source_.empty() || !alIsSource(this->audioSource_))
+ if (source_.empty())
return;
this->soundBuffer_ = SoundManager::getInstance().getSoundBuffer(this->source_);
if (this->soundBuffer_ == NULL)
return;
- alSourcei(this->audioSource_, AL_BUFFER, this->soundBuffer_->getBuffer());
- if (ALuint error = alGetError())
+ if (alIsSource(this->audioSource_))
{
- COUT(1) << "Sound Error: Could not load file \"" << source << "\": " << SoundManager::getALErrorString(error) << std::endl;
- return;
- }
+ alSourcei(this->audioSource_, AL_BUFFER, this->soundBuffer_->getBuffer());
+ if (ALuint error = alGetError())
+ {
+ COUT(1) << "Sound Error: Could not set buffer \"" << source << "\": " << SoundManager::getALErrorString(error) << std::endl;
+ return;
+ }
- alSource3f(this->audioSource_, AL_POSITION, 0, 0, 0);
- this->updateVolume();
- this->setPitch(this->getPitch());
- this->setLooping(getLooping());
- if (this->isPlaying() || this->isPaused())
- {
- alSourcePlay(this->audioSource_);
- if (int error = alGetError())
- COUT(2) << "Sound: Error playing sound: " << error << std::endl;
+ if (this->isPlaying() || this->isPaused())
+ {
+ alSourcePlay(this->audioSource_);
+ if (int error = alGetError())
+ COUT(2) << "Sound: Error playing sound: " << SoundManager::getALErrorString(error) << std::endl;
+ }
+ if (this->isPaused())
+ alSourcePause(this->audioSource_);
}
- if (this->isPaused())
- alSourcePause(this->audioSource_);
}
void BaseSound::stateChanged()
Modified: code/branches/presentation2/src/orxonox/sound/BaseSound.h
===================================================================
--- code/branches/presentation2/src/orxonox/sound/BaseSound.h 2009-12-11 01:05:58 UTC (rev 6321)
+++ code/branches/presentation2/src/orxonox/sound/BaseSound.h 2009-12-11 13:15:43 UTC (rev 6322)
@@ -95,6 +95,7 @@
Playing,
Paused
};
+ virtual void initialiseSource();
ALint getSourceState() const;
ALuint audioSource_;
Modified: code/branches/presentation2/src/orxonox/sound/SoundManager.cc
===================================================================
--- code/branches/presentation2/src/orxonox/sound/SoundManager.cc 2009-12-11 01:05:58 UTC (rev 6321)
+++ code/branches/presentation2/src/orxonox/sound/SoundManager.cc 2009-12-11 13:15:43 UTC (rev 6322)
@@ -86,7 +86,7 @@
#ifdef ORXONOX_PLATFORM_WINDOWS
COUT(1) << "Sound: Just getting the DLL with the dependencies is not enough for Windows (esp. Windows 7)!" << std::endl;
#endif
- ThrowException(InitialisationFailed, "Sound: OpenAL error: Could not open sound device.");
+ ThrowException(InitialisationFailed, "Sound Error: Could not open sound device.");
}
Loki::ScopeGuard closeDeviceGuard = Loki::MakeGuard(&alcCloseDevice, this->device_);
@@ -99,6 +99,7 @@
ThrowException(InitialisationFailed, "Sound Error: Could not use ALC context");
GameMode::setPlaysSound(true);
+ Loki::ScopeGuard resetPlaysSoundGuard = Loki::MakeGuard(&GameMode::setPlaysSound, false);
// Get some information about the sound
if (const char* version = alGetString(AL_VERSION))
@@ -109,11 +110,6 @@
COUT(4) << "Sound: --- Supported MIME Types: " << types << std::endl;
else
COUT(2) << "Sound Warning: MIME Type retrieval failed: " << alutGetErrorString(alutGetError()) << std::endl;
-
- // Disarm guards
- alutExitGuard.Dismiss();
- closeDeviceGuard.Dismiss();
- desroyContextGuard.Dismiss();
this->setVolumeInternal(1.0, SoundType::none);
this->setVolumeInternal(1.0, SoundType::ambient);
@@ -125,6 +121,29 @@
this->setConfigValues();
+ // Try to get at least one source
+ ALuint source;
+ alGenSources(1, &source);
+ if (!alGetError() && alIsSource(source))
+ this->soundSources_.push_back(source);
+ else
+ ThrowException(InitialisationFailed, "Sound Error: Could not even create a single source");
+ // Get the rest of the sources
+ alGenSources(1, &source);
+ unsigned int count = 1;
+ while (alIsSource(source) && !alGetError() && count <= this->maxSources_)
+ {
+ this->soundSources_.push_back(source);
+ alGenSources(1, &source);
+ ++count;
+ }
+
+ // Disarm guards
+ alutExitGuard.Dismiss();
+ closeDeviceGuard.Dismiss();
+ desroyContextGuard.Dismiss();
+ resetPlaysSoundGuard.Dismiss();
+
COUT(4) << "Sound: Initialisation complete" << std::endl;
}
@@ -163,18 +182,21 @@
SetConfigValue(crossFadeStep_, 0.2f)
.description("Determines how fast sounds should fade, per second.")
.callback(this, &SoundManager::checkFadeStepValidity);
-
+
SetConfigValue(soundVolume_, 1.0f)
.description("Defines the overall volume.")
.callback(this, &SoundManager::checkSoundVolumeValidity);
-
+
SetConfigValue(ambientVolume_, 1.0f)
.description("Defines the ambient volume.")
.callback(this, &SoundManager::checkAmbientVolumeValidity);
-
+
SetConfigValue(effectsVolume_, 1.0f)
.description("Defines the effects volume.")
.callback(this, &SoundManager::checkEffectsVolumeValidity);
+
+ SetConfigValue(maxSources_, 1024)
+ .description("Maximum number of sources to be made available");
}
std::string SoundManager::getALErrorString(ALenum code)
@@ -594,4 +616,30 @@
this->soundBuffers_.erase(it);
}
}
+
+ ALuint SoundManager::getSoundSource()
+ {
+ if (!this->soundSources_.empty())
+ {
+ ALuint source = this->soundSources_.back();
+ this->soundSources_.pop_back();
+ return source;
+ }
+ else
+ {
+ // Return no source ID
+ ALuint source = 123456789;
+ while (alIsSource(++source));
+ return source;
+ }
+ }
+
+ void SoundManager::releaseSoundSource(ALuint source)
+ {
+#ifndef NDEBUG
+ for (std::vector<ALuint>::const_iterator it = this->soundSources_.begin(); it != this->soundSources_.end(); ++it)
+ assert((*it) != source);
+#endif
+ this->soundSources_.push_back(source);
+ }
}
Modified: code/branches/presentation2/src/orxonox/sound/SoundManager.h
===================================================================
--- code/branches/presentation2/src/orxonox/sound/SoundManager.h 2009-12-11 01:05:58 UTC (rev 6321)
+++ code/branches/presentation2/src/orxonox/sound/SoundManager.h 2009-12-11 13:15:43 UTC (rev 6322)
@@ -101,6 +101,9 @@
shared_ptr<SoundBuffer> getSoundBuffer(const std::string& filename);
void releaseSoundBuffer(const shared_ptr<SoundBuffer>& buffer, bool bPoolBuffer);
+ ALuint getSoundSource();
+ void releaseSoundSource(ALuint source);
+
static std::string getALErrorString(ALenum error);
private:
@@ -143,6 +146,9 @@
EffectsPoolList effectsPool_;
typedef std::map<std::string, shared_ptr<SoundBuffer> > SoundBufferMap;
SoundBufferMap soundBuffers_;
+
+ unsigned int maxSources_;
+ std::vector<ALuint> soundSources_;
static SoundManager* singletonPtr_s;
}; // tolua_export
Modified: code/branches/presentation2/src/orxonox/sound/WorldSound.cc
===================================================================
--- code/branches/presentation2/src/orxonox/sound/WorldSound.cc 2009-12-11 01:05:58 UTC (rev 6321)
+++ code/branches/presentation2/src/orxonox/sound/WorldSound.cc 2009-12-11 13:15:43 UTC (rev 6322)
@@ -75,6 +75,12 @@
XMLPortEventState(WorldSound, BaseObject, "play", play, xmlelement, mode);
}
+ void WorldSound::initialiseSource()
+ {
+ BaseSound::initialiseSource();
+ this->tick(0); // update position, orientation and velocity
+ }
+
void WorldSound::tick(float dt)
{
if (alIsSource(this->audioSource_))
Modified: code/branches/presentation2/src/orxonox/sound/WorldSound.h
===================================================================
--- code/branches/presentation2/src/orxonox/sound/WorldSound.h 2009-12-11 01:05:58 UTC (rev 6321)
+++ code/branches/presentation2/src/orxonox/sound/WorldSound.h 2009-12-11 13:15:43 UTC (rev 6322)
@@ -57,6 +57,7 @@
private:
void registerVariables();
+ void initialiseSource();
};
}
More information about the Orxonox-commit
mailing list