Update sound engine with some sound fixes

* Refactor client module
This commit is contained in:
Eduardo Bart
2013-01-16 16:46:42 -02:00
parent 52ede065fc
commit 62cd3d04e1
11 changed files with 223 additions and 174 deletions

View File

@@ -46,21 +46,21 @@ void SoundManager::init()
g_logger.error(stdext::format("unable to create audio context: %s", alcGetString(m_device, alcGetError(m_device))));
return;
}
alcMakeContextCurrent(m_context);
m_musicEnabled = true;
m_soundEnabled = true;
if(alcMakeContextCurrent(m_context) != ALC_TRUE) {
g_logger.error(stdext::format("unable to make context current: %s", alcGetString(m_device, alcGetError(m_device))));
return;
}
}
void SoundManager::terminate()
{
ensureContext();
m_sources.clear();
m_buffers.clear();
m_musicSource = nullptr;
m_currentMusic = "";
m_musicEnabled = false;
m_soundEnabled = false;
m_channels.clear();
m_audioEnabled = false;
alcMakeContextCurrent(nullptr);
@@ -85,6 +85,7 @@ void SoundManager::poll()
lastUpdate = now;
ensureContext();
for(auto it = m_sources.begin(); it != m_sources.end();) {
SoundSourcePtr source = *it;
@@ -96,10 +97,8 @@ void SoundManager::poll()
++it;
}
if(m_musicSource) {
m_musicSource->update();
if(!m_musicSource->isPlaying())
m_musicSource = nullptr;
for(auto it : m_channels) {
it.second->update();
}
if(m_context) {
@@ -107,18 +106,33 @@ void SoundManager::poll()
}
}
void SoundManager::setAudioEnabled(bool enable)
{
if(m_audioEnabled == enable)
return;
m_audioEnabled = enable;
if(!enable) {
ensureContext();
for(const SoundSourcePtr& source : m_sources) {
source->stop();
}
}
}
void SoundManager::preload(std::string filename)
{
filename = g_resources.resolvePath(filename);
filename = resolveSoundFile(filename);
auto it = m_buffers.find(filename);
if(it != m_buffers.end())
return;
ensureContext();
SoundFilePtr soundFile = SoundFile::loadSoundFile(filename);
// only keep small files
if(soundFile->getSize() > MAX_CACHE_SIZE)
if(!soundFile || soundFile->getSize() > MAX_CACHE_SIZE)
return;
SoundBufferPtr buffer = SoundBufferPtr(new SoundBuffer);
@@ -126,85 +140,55 @@ void SoundManager::preload(std::string filename)
m_buffers[filename] = buffer;
}
void SoundManager::enableSound(bool enable)
SoundSourcePtr SoundManager::play(std::string filename, float fadetime, float gain)
{
if(!isAudioEnabled())
return;
}
if(!m_audioEnabled)
return nullptr;
void SoundManager::play(std::string filename)
{
if(!m_soundEnabled || filename.empty())
return;
ensureContext();
filename = g_resources.resolvePath(filename);
if(gain == 0)
gain = 1.0f;
filename = resolveSoundFile(filename);
SoundSourcePtr soundSource = createSoundSource(filename);
if(!soundSource) {
g_logger.error(stdext::format("unable to play '%s'", filename));
return;
return nullptr;
}
soundSource->setName(filename);
soundSource->setRelative(true);
soundSource->setGain(gain);
if(fadetime > 0) {
soundSource->setFading(StreamSoundSource::FadingOn, fadetime);
}
soundSource->play();
m_sources.push_back(soundSource);
return soundSource;
}
void SoundManager::enableMusic(bool enable)
SoundChannelPtr SoundManager::getChannel(int channel)
{
if(!isAudioEnabled())
return;
m_musicEnabled = enable;
if(enable && !m_currentMusic.empty())
playMusic(m_currentMusic, 3.0f);
else
m_musicSource = nullptr;
ensureContext();
if(!m_channels[channel])
m_channels[channel] = SoundChannelPtr(new SoundChannel(channel));
return m_channels[channel];
}
void SoundManager::playMusic(std::string filename, float fadetime)
void SoundManager::stopAll()
{
if(filename.empty())
return;
filename = g_resources.resolvePath(filename);
if(m_currentMusic == filename && m_musicSource)
return;
if(!m_musicEnabled)
return;
if(filename.empty()) {
m_musicSource = nullptr;
return;
ensureContext();
for(const SoundSourcePtr& source : m_sources) {
source->stop();
}
m_musicSource = createSoundSource(filename);
if(!m_musicSource) {
g_logger.error(stdext::format("unable to play '%s'", filename));
return;
}
m_musicSource->setRelative(true);
if(fadetime > 0) {
m_musicSource->setGain(0);
m_musicSource->setFading(StreamSoundSource::FadingOn, fadetime);
}
m_musicSource->play();
}
void SoundManager::stopMusic(float fadetime)
{
if(m_musicSource) {
if(fadetime > 0)
m_musicSource->setFading(StreamSoundSource::FadingOff, 3.0f);
else
m_musicSource->stop();
for(auto it : m_channels) {
it.second->stop();
}
}
@@ -212,51 +196,69 @@ SoundSourcePtr SoundManager::createSoundSource(const std::string& filename)
{
SoundSourcePtr source;
auto it = m_buffers.find(filename);
if(it != m_buffers.end()) {
source = SoundSourcePtr(new SoundSource);
source->setBuffer(it->second);
} else {
SoundFilePtr soundFile = SoundFile::loadSoundFile(filename);
if(!soundFile)
return nullptr;
if(soundFile->getSize() <= MAX_CACHE_SIZE) {
try {
auto it = m_buffers.find(filename);
if(it != m_buffers.end()) {
source = SoundSourcePtr(new SoundSource);
SoundBufferPtr buffer = SoundBufferPtr(new SoundBuffer);
buffer->fillBuffer(soundFile);
source->setBuffer(buffer);
m_buffers[filename] = buffer;
g_logger.warning(stdext::format("uncached sound '%s' requested to be played", filename));
source->setBuffer(it->second);
} else {
StreamSoundSourcePtr streamSource(new StreamSoundSource);
streamSource->setSoundFile(soundFile);
source = streamSource;
SoundFilePtr soundFile = SoundFile::loadSoundFile(filename);
if(!soundFile)
return nullptr;
#if defined __linux && !defined OPENGL_ES
// due to OpenAL implementation bug, stereo buffers are always downmixed to mono on linux systems
// this is hack to work around the issue
// solution taken from http://opensource.creative.com/pipermail/openal/2007-April/010355.html
if(soundFile->getSampleFormat() == AL_FORMAT_STEREO16) {
CombinedSoundSourcePtr combinedSource(new CombinedSoundSource);
if(soundFile->getSize() <= MAX_CACHE_SIZE) {
source = SoundSourcePtr(new SoundSource);
SoundBufferPtr buffer = SoundBufferPtr(new SoundBuffer);
buffer->fillBuffer(soundFile);
source->setBuffer(buffer);
m_buffers[filename] = buffer;
g_logger.warning(stdext::format("uncached sound '%s' requested to be played", filename));
} else {
StreamSoundSourcePtr streamSource(new StreamSoundSource);
streamSource->setSoundFile(soundFile);
source = streamSource;
streamSource->downMix(StreamSoundSource::DownMixLeft);
streamSource->setRelative(true);
streamSource->setPosition(Point(-128, 0));
combinedSource->addSource(streamSource);
#if defined __linux && !defined OPENGL_ES
// due to OpenAL implementation bug, stereo buffers are always downmixed to mono on linux systems
// this is hack to work around the issue
// solution taken from http://opensource.creative.com/pipermail/openal/2007-April/010355.html
if(soundFile->getSampleFormat() == AL_FORMAT_STEREO16) {
CombinedSoundSourcePtr combinedSource(new CombinedSoundSource);
streamSource = StreamSoundSourcePtr(new StreamSoundSource);
streamSource->setSoundFile(SoundFile::loadSoundFile(filename));
streamSource->downMix(StreamSoundSource::DownMixRight);
streamSource->setRelative(true);
streamSource->setPosition(Point(128,0));
combinedSource->addSource(streamSource);
streamSource->downMix(StreamSoundSource::DownMixLeft);
streamSource->setRelative(true);
streamSource->setPosition(Point(-128, 0));
combinedSource->addSource(streamSource);
source = combinedSource;
streamSource = StreamSoundSourcePtr(new StreamSoundSource);
streamSource->setSoundFile(SoundFile::loadSoundFile(filename));
streamSource->downMix(StreamSoundSource::DownMixRight);
streamSource->setRelative(true);
streamSource->setPosition(Point(128,0));
combinedSource->addSource(streamSource);
source = combinedSource;
}
#endif
}
#endif
}
} catch(std::exception& e) {
g_logger.error(stdext::format("failed to load sound source: '%s'", e.what()));
return nullptr;
}
return source;
}
std::string SoundManager::resolveSoundFile(std::string file)
{
file = g_resources.guessFileType(file, "ogg");
file = g_resources.resolvePath(file);
return file;
}
void SoundManager::ensureContext()
{
if(m_context)
alcMakeContextCurrent(m_context);
}