diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index 146776442..a6258babe 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -39,6 +39,26 @@ const float UnitsPerMeter = 69.99125109f; const int sLoudnessFPS = 20; // loudness values per second of audio +ALCenum checkALCError(ALCdevice *device, const char *func, int line) +{ + ALCenum err = alcGetError(device); + if(err != ALC_NO_ERROR) + std::cerr<< ">>>>>>>>> ALC error "<>>>>>>>> AL error "< void convertPointer(T& dest, R src) @@ -144,7 +164,7 @@ void LoadEffect(ALuint effect, const EFXEAXREVERBPROPERTIES &props) alEffectf(effect, AL_REVERB_ROOM_ROLLOFF_FACTOR, props.flRoomRolloffFactor); alEffecti(effect, AL_REVERB_DECAY_HFLIMIT, props.iDecayHFLimit ? AL_TRUE : AL_FALSE); } - alGetError(); + getALError(); } } @@ -152,30 +172,6 @@ void LoadEffect(ALuint effect, const EFXEAXREVERBPROPERTIES &props) namespace MWSound { -static void fail(const std::string &msg) -{ throw std::runtime_error("OpenAL exception: " + msg); } - -static void throwALCerror(ALCdevice *device) -{ - ALCenum err = alcGetError(device); - if(err != ALC_NO_ERROR) - { - const ALCchar *errstring = alcGetString(device, err); - fail(errstring ? errstring : ""); - } -} - -static void throwALerror() -{ - ALenum err = alGetError(); - if(err != AL_NO_ERROR) - { - const ALchar *errstring = alGetString(err); - fail(errstring ? errstring : ""); - } -} - - static ALenum getALFormat(ChannelConfig chans, SampleType type) { static const struct { @@ -268,7 +264,8 @@ static ALenum getALFormat(ChannelConfig chans, SampleType type) } } - fail(std::string("Unsupported sound format (")+getChannelConfigName(chans)+", "+getSampleTypeName(type)+")"); + std::cerr<< "Unsupported sound format ("<getInfo(&srate, &chans, &type); - mFormat = getALFormat(chans, type); - mSampleRate = srate; +OpenAL_SoundStream::~OpenAL_SoundStream() +{ + if(mBuffers[0] && alIsBuffer(mBuffers[0])) + alDeleteBuffers(sNumBuffers, mBuffers); + alGetError(); - switch(type) - { - case SampleType_UInt8: mSilence = 0x80; break; - case SampleType_Int16: mSilence = 0x00; break; - case SampleType_Float32: mSilence = 0x00; break; - } + mDecoder->close(); +} + +bool OpenAL_SoundStream::init(bool getLoudnessData) +{ + alGenBuffers(sNumBuffers, mBuffers); + ALenum err = getALError(); + if(err != AL_NO_ERROR) + return false; - mFrameSize = framesToBytes(1, chans, type); - mBufferSize = static_cast(sBufferLength*srate); - mBufferSize *= mFrameSize; + ChannelConfig chans; + SampleType type; - if (getLoudnessData) - mLoudnessAnalyzer.reset(new Sound_Loudness(sLoudnessFPS, mSampleRate, chans, type)); - } - catch(std::exception&) + mDecoder->getInfo(&mSampleRate, &chans, &type); + mFormat = getALFormat(chans, type); + if(!mFormat) return false; + + switch(type) { - alDeleteBuffers(sNumBuffers, mBuffers); - alGetError(); - throw; + case SampleType_UInt8: mSilence = 0x80; break; + case SampleType_Int16: mSilence = 0x00; break; + case SampleType_Float32: mSilence = 0x00; break; } - mIsFinished = false; -} -OpenAL_SoundStream::~OpenAL_SoundStream() -{ - alDeleteBuffers(sNumBuffers, mBuffers); - alGetError(); - mDecoder->close(); + mFrameSize = framesToBytes(1, chans, type); + mBufferSize = static_cast(sBufferLength*mSampleRate); + mBufferSize *= mFrameSize; + + if (getLoudnessData) + mLoudnessAnalyzer.reset(new Sound_Loudness(sLoudnessFPS, mSampleRate, chans, type)); + + mIsFinished = false; + return true; } bool OpenAL_SoundStream::isPlaying() @@ -444,7 +446,7 @@ bool OpenAL_SoundStream::isPlaying() ALint state; alGetSourcei(mSource, AL_SOURCE_STATE, &state); - throwALerror(); + getALError(); if(state == AL_PLAYING || state == AL_PAUSED) return true; @@ -467,7 +469,7 @@ double OpenAL_SoundStream::getStreamDelay() const d = (double)inqueue / (double)mSampleRate; } - throwALerror(); + getALError(); return d; } @@ -493,7 +495,7 @@ double OpenAL_SoundStream::getStreamOffset() const t = (double)mDecoder->getSampleOffset() / (double)mSampleRate; } - throwALerror(); + getALError(); return t; } @@ -590,7 +592,7 @@ std::vector OpenAL_Output::enumerate() return devlist; } -void OpenAL_Output::init(const std::string &devname) +bool OpenAL_Output::init(const std::string &devname) { deinit(); @@ -598,9 +600,10 @@ void OpenAL_Output::init(const std::string &devname) if(!mDevice) { if(devname.empty()) - fail("Failed to open default device"); + std::cerr<< "Failed to open default audio device" <(maxmono+maxstereo, 256); + maxtotal = std::min(maxmono+maxstereo, 256); if (maxtotal == 0) // workaround for broken implementations maxtotal = 256; - for(size_t i = 0;i < maxtotal;i++) - { - ALuint src = 0; - alGenSources(1, &src); - throwALerror(); - mFreeSources.push_back(src); - } } - catch(std::exception &e) + for(size_t i = 0;i < maxtotal;i++) { - std::cout <<"Error: "< OpenAL_Output::enumerateHrtf() { - if(!mDevice) - fail("Device not initialized"); - std::vector ret; - if(!alcIsExtensionPresent(mDevice, "ALC_SOFT_HRTF")) + + if(!mDevice || !alcIsExtensionPresent(mDevice, "ALC_SOFT_HRTF")) return ret; LPALCGETSTRINGISOFT alcGetStringiSOFT = 0; @@ -816,7 +831,6 @@ void OpenAL_Output::enableHrtf(const std::string &hrtfname, bool auto_enable) return; } - LPALCGETSTRINGISOFT alcGetStringiSOFT = 0; getALCFunc(alcGetStringiSOFT, mDevice, "alcGetStringiSOFT"); @@ -891,7 +905,7 @@ void OpenAL_Output::disableHrtf() Sound_Handle OpenAL_Output::loadSound(const std::string &fname) { - throwALerror(); + getALError(); DecoderPtr decoder = mManager.getDecoder(); // Workaround: Bethesda at some point converted some of the files to mp3, but the references were kept as .wav. @@ -914,20 +928,20 @@ Sound_Handle OpenAL_Output::loadSound(const std::string &fname) decoder->getInfo(&srate, &chans, &type); format = getALFormat(chans, type); + if(!format) return nullptr; decoder->readAll(data); decoder->close(); ALuint buf = 0; - try { - alGenBuffers(1, &buf); - alBufferData(buf, format, &data[0], data.size(), srate); - throwALerror(); - } - catch(...) { + alGenBuffers(1, &buf); + alBufferData(buf, format, &data[0], data.size(), srate); + if(getALError() != AL_NO_ERROR) + { if(buf && alIsBuffer(buf)) alDeleteBuffers(1, &buf); - throw; + getALError(); + return nullptr; } return MAKE_PTRID(buf); } @@ -952,6 +966,7 @@ void OpenAL_Output::unloadSound(Sound_Handle data) } } alDeleteBuffers(1, &buffer); + getALError(); } size_t OpenAL_Output::getSoundDataSize(Sound_Handle data) const @@ -960,7 +975,7 @@ size_t OpenAL_Output::getSoundDataSize(Sound_Handle data) const ALint size = 0; alGetBufferi(buffer, AL_SIZE, &size); - throwALerror(); + getALError(); return (ALuint)size; } @@ -1067,65 +1082,63 @@ void OpenAL_Output::updateCommon(ALuint source, const osg::Vec3f& pos, ALfloat m } -void OpenAL_Output::playSound(Sound *sound, Sound_Handle data, float offset) +bool OpenAL_Output::playSound(Sound *sound, Sound_Handle data, float offset) { ALuint source; if(mFreeSources.empty()) - fail("No free sources"); + { + std::cerr<< "No free sources!" <getPosition(), sound->getRealVolume(), sound->getPitch(), - sound->getIsLooping(), sound->getUseEnv()); - - alSourcef(source, AL_SEC_OFFSET, offset); - throwALerror(); - alSourcei(source, AL_BUFFER, GET_PTRID(data)); - alSourcePlay(source); - throwALerror(); + initCommon2D(source, sound->getPosition(), sound->getRealVolume(), sound->getPitch(), + sound->getIsLooping(), sound->getUseEnv()); + alSourcef(source, AL_SEC_OFFSET, offset); + if(getALError() != AL_NO_ERROR) + return false; - mActiveSounds.push_back(sound); - } - catch(std::exception&) { - mFreeSources.push_back(source); - throw; - } + alSourcei(source, AL_BUFFER, GET_PTRID(data)); + alSourcePlay(source); + if(getALError() != AL_NO_ERROR) + return false; + mFreeSources.pop_front(); sound->mHandle = MAKE_PTRID(source); + mActiveSounds.push_back(sound); + + return true; } -void OpenAL_Output::playSound3D(Sound *sound, Sound_Handle data, float offset) +bool OpenAL_Output::playSound3D(Sound *sound, Sound_Handle data, float offset) { ALuint source; if(mFreeSources.empty()) - fail("No free sources"); + { + std::cerr<< "No free sources!" <getPosition(), sound->getMinDistance(), sound->getMaxDistance(), - sound->getRealVolume(), sound->getPitch(), sound->getIsLooping(), - sound->getUseEnv()); - - alSourcef(source, AL_SEC_OFFSET, offset); - throwALerror(); + initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(), + sound->getRealVolume(), sound->getPitch(), sound->getIsLooping(), + sound->getUseEnv()); + alSourcef(source, AL_SEC_OFFSET, offset); + if(getALError() != AL_NO_ERROR) + return false; - alSourcei(source, AL_BUFFER, GET_PTRID(data)); - alSourcePlay(source); - throwALerror(); - - mActiveSounds.push_back(sound); - } - catch(std::exception&) { - mFreeSources.push_back(source); - throw; - } + alSourcei(source, AL_BUFFER, GET_PTRID(data)); + alSourcePlay(source); + if(getALError() != AL_NO_ERROR) + return false; + mFreeSources.pop_front(); sound->mHandle = MAKE_PTRID(source); + mActiveSounds.push_back(sound); + + return true; } void OpenAL_Output::finishSound(Sound *sound) @@ -1139,6 +1152,7 @@ void OpenAL_Output::finishSound(Sound *sound) // the initial queue already played when it hasn't. alSourceRewind(source); alSourcei(source, AL_BUFFER, 0); + getALError(); mFreeSources.push_back(source); mActiveSounds.erase(std::find(mActiveSounds.begin(), mActiveSounds.end(), sound)); @@ -1148,10 +1162,10 @@ bool OpenAL_Output::isSoundPlaying(Sound *sound) { if(!sound->mHandle) return false; ALuint source = GET_PTRID(sound->mHandle); - ALint state; + ALint state = AL_STOPPED; alGetSourcei(source, AL_SOURCE_STATE, &state); - throwALerror(); + getALError(); return state == AL_PLAYING || state == AL_PAUSED; } @@ -1163,69 +1177,68 @@ void OpenAL_Output::updateSound(Sound *sound) updateCommon(source, sound->getPosition(), sound->getMaxDistance(), sound->getRealVolume(), sound->getPitch(), sound->getUseEnv(), sound->getIs3D()); + getALError(); } -void OpenAL_Output::streamSound(DecoderPtr decoder, Stream *sound) +bool OpenAL_Output::streamSound(DecoderPtr decoder, Stream *sound) { - OpenAL_SoundStream *stream = 0; - ALuint source; - if(mFreeSources.empty()) - fail("No free sources"); - source = mFreeSources.front(); - mFreeSources.pop_front(); + { + std::cerr<< "No free sources!" <getIsLooping()) std::cout <<"Warning: cannot loop stream \""<getName()<<"\""<< std::endl; - try { - initCommon2D(source, sound->getPosition(), sound->getRealVolume(), sound->getPitch(), - false, sound->getUseEnv()); - throwALerror(); + initCommon2D(source, sound->getPosition(), sound->getRealVolume(), sound->getPitch(), + false, sound->getUseEnv()); + if(getALError() != AL_NO_ERROR) + return false; - stream = new OpenAL_SoundStream(source, decoder); - mStreamThread->add(stream); - mActiveStreams.push_back(sound); - } - catch(std::exception&) { - mStreamThread->remove(stream); + OpenAL_SoundStream *stream = new OpenAL_SoundStream(source, std::move(decoder)); + if(!stream->init()) + { delete stream; - mFreeSources.push_back(source); - throw; + return false; } + mStreamThread->add(stream); + mFreeSources.pop_front(); sound->mHandle = stream; + mActiveStreams.push_back(sound); + return true; } -void OpenAL_Output::streamSound3D(DecoderPtr decoder, Stream *sound, bool getLoudnessData) +bool OpenAL_Output::streamSound3D(DecoderPtr decoder, Stream *sound, bool getLoudnessData) { - OpenAL_SoundStream *stream = 0; - ALuint source; - if(mFreeSources.empty()) - fail("No free sources"); - source = mFreeSources.front(); - mFreeSources.pop_front(); + { + std::cerr<< "No free sources!" <getIsLooping()) std::cout <<"Warning: cannot loop stream \""<getName()<<"\""<< std::endl; - try { - initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(), - sound->getRealVolume(), sound->getPitch(), false, sound->getUseEnv()); - throwALerror(); + initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(), + sound->getRealVolume(), sound->getPitch(), false, sound->getUseEnv()); + if(getALError() != AL_NO_ERROR) + return false; - stream = new OpenAL_SoundStream(source, decoder, getLoudnessData); - mStreamThread->add(stream); - mActiveStreams.push_back(sound); - } - catch(std::exception&) { - mStreamThread->remove(stream); + OpenAL_SoundStream *stream = new OpenAL_SoundStream(source, std::move(decoder)); + if(!stream->init(getLoudnessData)) + { delete stream; - mFreeSources.push_back(source); - throw; + return false; } + mStreamThread->add(stream); + mFreeSources.pop_front(); sound->mHandle = stream; + mActiveStreams.push_back(sound); + return true; } void OpenAL_Output::finishStream(Stream *sound) @@ -1242,6 +1255,7 @@ void OpenAL_Output::finishStream(Stream *sound) // the initial queue already played when it hasn't. alSourceRewind(source); alSourcei(source, AL_BUFFER, 0); + getALError(); mFreeSources.push_back(source); mActiveStreams.erase(std::find(mActiveStreams.begin(), mActiveStreams.end(), sound)); @@ -1288,6 +1302,7 @@ void OpenAL_Output::updateStream(Stream *sound) updateCommon(source, sound->getPosition(), sound->getMaxDistance(), sound->getRealVolume(), sound->getPitch(), sound->getUseEnv(), sound->getIs3D()); + getALError(); } @@ -1346,7 +1361,7 @@ void OpenAL_Output::updateListener(const osg::Vec3f &pos, const osg::Vec3f &atdi (env == Env_Underwater) ? mWaterEffect : mDefaultEffect ); } - throwALerror(); + getALError(); } mListenerPos = pos; @@ -1374,8 +1389,8 @@ void OpenAL_Output::pauseSounds(int types) } if(!sources.empty()) { - alSourcePausev(sources.size(), &sources[0]); - throwALerror(); + alSourcePausev(sources.size(), sources.data()); + getALError(); } } @@ -1399,8 +1414,8 @@ void OpenAL_Output::resumeSounds(int types) } if(!sources.empty()) { - alSourcePlayv(sources.size(), &sources[0]); - throwALerror(); + alSourcePlayv(sources.size(), sources.data()); + getALError(); } } diff --git a/apps/openmw/mwsound/openal_output.hpp b/apps/openmw/mwsound/openal_output.hpp index 777b9207f..05f9c5090 100644 --- a/apps/openmw/mwsound/openal_output.hpp +++ b/apps/openmw/mwsound/openal_output.hpp @@ -59,7 +59,7 @@ namespace MWSound public: virtual std::vector enumerate(); - virtual void init(const std::string &devname=std::string()); + virtual bool init(const std::string &devname=std::string()); virtual void deinit(); virtual std::vector enumerateHrtf(); @@ -70,14 +70,14 @@ namespace MWSound virtual void unloadSound(Sound_Handle data); virtual size_t getSoundDataSize(Sound_Handle data) const; - virtual void playSound(Sound *sound, Sound_Handle data, float offset); - virtual void playSound3D(Sound *sound, Sound_Handle data, float offset); + virtual bool playSound(Sound *sound, Sound_Handle data, float offset); + virtual bool playSound3D(Sound *sound, Sound_Handle data, float offset); virtual void finishSound(Sound *sound); virtual bool isSoundPlaying(Sound *sound); virtual void updateSound(Sound *sound); - virtual void streamSound(DecoderPtr decoder, Stream *sound); - virtual void streamSound3D(DecoderPtr decoder, Stream *sound, bool getLoudnessData); + virtual bool streamSound(DecoderPtr decoder, Stream *sound); + virtual bool streamSound3D(DecoderPtr decoder, Stream *sound, bool getLoudnessData); virtual void finishStream(Stream *sound); virtual double getStreamDelay(Stream *sound); virtual double getStreamOffset(Stream *sound); diff --git a/apps/openmw/mwsound/sound_output.hpp b/apps/openmw/mwsound/sound_output.hpp index 907a601b5..01dc8b5b9 100644 --- a/apps/openmw/mwsound/sound_output.hpp +++ b/apps/openmw/mwsound/sound_output.hpp @@ -24,7 +24,7 @@ namespace MWSound SoundManager &mManager; virtual std::vector enumerate() = 0; - virtual void init(const std::string &devname=std::string()) = 0; + virtual bool init(const std::string &devname=std::string()) = 0; virtual void deinit() = 0; virtual std::vector enumerateHrtf() = 0; @@ -35,14 +35,14 @@ namespace MWSound virtual void unloadSound(Sound_Handle data) = 0; virtual size_t getSoundDataSize(Sound_Handle data) const = 0; - virtual void playSound(Sound *sound, Sound_Handle data, float offset) = 0; - virtual void playSound3D(Sound *sound, Sound_Handle data, float offset) = 0; + virtual bool playSound(Sound *sound, Sound_Handle data, float offset) = 0; + virtual bool playSound3D(Sound *sound, Sound_Handle data, float offset) = 0; virtual void finishSound(Sound *sound) = 0; virtual bool isSoundPlaying(Sound *sound) = 0; virtual void updateSound(Sound *sound) = 0; - virtual void streamSound(DecoderPtr decoder, Stream *sound) = 0; - virtual void streamSound3D(DecoderPtr decoder, Stream *sound, bool getLoudnessData) = 0; + virtual bool streamSound(DecoderPtr decoder, Stream *sound) = 0; + virtual bool streamSound3D(DecoderPtr decoder, Stream *sound, bool getLoudnessData) = 0; virtual void finishStream(Stream *sound) = 0; virtual double getStreamDelay(Stream *sound) = 0; virtual double getStreamOffset(Stream *sound) = 0; diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 25af9add8..51ce67096 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -89,40 +89,42 @@ namespace MWSound std::cout << "Sound output: " << SOUND_OUT << std::endl; std::cout << "Sound decoder: " << SOUND_IN << std::endl; - try { - std::vector names = mOutput->enumerate(); - std::cout <<"Enumerated output devices:"<< std::endl; - for(size_t i = 0;i < names.size();i++) - std::cout <<" "<init(devname); - } - catch(std::exception &e) { - if(devname.empty()) - throw; - std::cerr <<"Failed to open device \""<init(); - Settings::Manager::setString("device", "Sound", ""); - } - - names = mOutput->enumerateHrtf(); - if(!names.empty()) - { - std::cout <<"Enumerated HRTF names:"<< std::endl; - for(size_t i = 0;i < names.size();i++) - std::cout <<" "< names = mOutput->enumerate(); + std::cout <<"Enumerated output devices:\n"; + std::for_each(names.cbegin(), names.cend(), + [](const std::string &name) -> void + { std::cout <<" "<disableHrtf(); - else if(!hrtfname.empty()) - mOutput->enableHrtf(hrtfname, hrtfstate<0); + std::string devname = Settings::Manager::getString("device", "Sound"); + bool inited = mOutput->init(devname); + if(!inited && !devname.empty()) + { + std::cerr<< "Failed to initialize device \""<init(); } - catch(std::exception &e) { - std::cout <<"Sound init failed: "<enumerateHrtf(); + if(!names.empty()) + { + std::cout<< "Enumerated HRTF names:\n"; + std::for_each(names.cbegin(), names.cend(), + [](const std::string &name) -> void + { std::cout<< " "<disableHrtf(); + else if(!hrtfname.empty()) + mOutput->enableHrtf(hrtfname, hrtfstate<0); } SoundManager::~SoundManager() @@ -186,8 +188,12 @@ namespace MWSound Sound_Buffer *SoundManager::lookupSound(const std::string &soundId) const { NameBufferMap::const_iterator snd = mBufferNameMap.find(soundId); - if(snd != mBufferNameMap.end()) return snd->second; - return 0; + if(snd != mBufferNameMap.end()) + { + Sound_Buffer *sfx = snd->second; + if(sfx->mHandle) return sfx; + } + return nullptr; } // Lookup a soundId for its sound data (resource name, local volume, @@ -201,15 +207,17 @@ namespace MWSound else { MWBase::World *world = MWBase::Environment::get().getWorld(); - const ESM::Sound *sound = world->getStore().get().find(soundId); + const ESM::Sound *sound = world->getStore().get().search(soundId); + if(!sound) return nullptr; sfx = insertSound(soundId, sound); } if(!sfx->mHandle) { sfx->mHandle = mOutput->loadSound(sfx->mResourceName); - mBufferCacheSize += mOutput->getSoundDataSize(sfx->mHandle); + if(!sfx->mHandle) return nullptr; + mBufferCacheSize += mOutput->getSoundDataSize(sfx->mHandle); if(mBufferCacheSize > mBufferCacheMax) { do { @@ -293,18 +301,24 @@ namespace MWSound static float minDistance = std::max(fAudioVoiceDefaultMinDistance * fAudioMinDistanceMult, 1.0f); static float maxDistance = std::max(fAudioVoiceDefaultMaxDistance * fAudioMaxDistanceMult, minDistance); + bool played; float basevol = volumeFromType(Play_TypeVoice); Stream *sound = getStreamRef(); if(playlocal) { sound->init(1.0f, basevol, 1.0f, Play_NoEnv|Play_TypeVoice|Play_2D); - mOutput->streamSound(decoder, sound); + played = mOutput->streamSound(decoder, sound); } else { sound->init(pos, 1.0f, basevol, 1.0f, minDistance, maxDistance, Play_Normal|Play_TypeVoice|Play_3D); - mOutput->streamSound3D(decoder, sound, true); + played = mOutput->streamSound3D(decoder, sound, true); + } + if(!played) + { + mUnusedStreams.push_back(sound); + return nullptr; } return sound; } @@ -351,23 +365,16 @@ namespace MWSound return; std::cout <<"Playing "<open(filename); + stopMusic(); - mMusic = getStreamRef(); - mMusic->init(1.0f, volumeFromType(Play_TypeMusic), 1.0f, - Play_NoEnv|Play_TypeMusic|Play_2D); - mOutput->streamSound(decoder, mMusic); - } - catch(std::exception &e) { - std::cout << "Music Error: " << e.what() << "\n"; - if(mMusic) - mUnusedStreams.push_back(mMusic); - mMusic = nullptr; - } + DecoderPtr decoder = getDecoder(); + decoder->open(filename); + + mMusic = getStreamRef(); + mMusic->init(1.0f, volumeFromType(Play_TypeMusic), 1.0f, + Play_NoEnv|Play_TypeMusic|Play_2D); + mOutput->streamSound(decoder, mMusic); } void SoundManager::advanceMusic(const std::string& filename) @@ -454,24 +461,20 @@ namespace MWSound { if(!mOutput->isInitialized()) return; - try - { - std::string voicefile = "Sound/"+filename; - mVFS->normalizeFilename(voicefile); - DecoderPtr decoder = loadVoice(voicefile); + std::string voicefile = "Sound/"+filename; - MWBase::World *world = MWBase::Environment::get().getWorld(); - const osg::Vec3f pos = world->getActorHeadTransform(ptr).getTrans(); + mVFS->normalizeFilename(voicefile); + DecoderPtr decoder = loadVoice(voicefile); - stopSay(ptr); - Stream *sound = playVoice(decoder, pos, (ptr == MWMechanics::getPlayer())); - mActiveSaySounds.insert(std::make_pair(ptr, sound)); - } - catch(std::exception &e) - { - std::cout <<"Sound Error: "<getActorHeadTransform(ptr).getTrans(); + + stopSay(ptr); + Stream *sound = playVoice(decoder, pos, (ptr == MWMechanics::getPlayer())); + if(!sound) return; + + mActiveSaySounds.insert(std::make_pair(ptr, sound)); } float SoundManager::getSaySoundLoudness(const MWWorld::ConstPtr &ptr) const @@ -490,21 +493,17 @@ namespace MWSound { if(!mOutput->isInitialized()) return; - try - { - std::string voicefile = "Sound/"+filename; - mVFS->normalizeFilename(voicefile); - DecoderPtr decoder = loadVoice(voicefile); + std::string voicefile = "Sound/"+filename; - stopSay(MWWorld::ConstPtr()); - mActiveSaySounds.insert(std::make_pair(MWWorld::ConstPtr(), - playVoice(decoder, osg::Vec3f(), true))); - } - catch(std::exception &e) - { - std::cout <<"Sound Error: "<normalizeFilename(voicefile); + DecoderPtr decoder = loadVoice(voicefile); + + stopSay(MWWorld::ConstPtr()); + Stream *sound = playVoice(decoder, osg::Vec3f(), true); + if(!sound) return; + + mActiveSaySounds.insert(std::make_pair(MWWorld::ConstPtr(), sound)); } bool SoundManager::sayDone(const MWWorld::ConstPtr &ptr) const @@ -535,22 +534,18 @@ namespace MWSound { if(!mOutput->isInitialized()) return nullptr; - Stream *track = getStreamRef(); - try - { - track->init(1.0f, volumeFromType(type), 1.0f, Play_NoEnv|type|Play_2D); - mOutput->streamSound(decoder, track); - TrackList::iterator iter = std::lower_bound(mActiveTracks.begin(), mActiveTracks.end(), track); - mActiveTracks.insert(iter, track); - } - catch(std::exception &e) + Stream *track = getStreamRef(); + track->init(1.0f, volumeFromType(type), 1.0f, Play_NoEnv|type|Play_2D); + if(!mOutput->streamSound(decoder, track)) { - std::cout <<"Sound Error: "<isInitialized()) return nullptr; - Sound *sound = nullptr; - try - { - Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId)); - float basevol = volumeFromType(type); - sound = getSoundRef(); - sound->init(volume * sfx->mVolume, basevol, pitch, mode|type|Play_2D); - mOutput->playSound(sound, sfx->mHandle, offset); - if(sfx->mUses++ == 0) - { - SoundList::iterator iter = std::find(mUnusedBuffers.begin(), mUnusedBuffers.end(), sfx); - if(iter != mUnusedBuffers.end()) - mUnusedBuffers.erase(iter); - } - mActiveSounds[MWWorld::ConstPtr()].push_back(std::make_pair(sound, sfx)); + Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId)); + if(!sfx) return nullptr; + + Sound *sound = getSoundRef(); + sound->init(volume * sfx->mVolume, volumeFromType(type), pitch, mode|type|Play_2D); + if(!mOutput->playSound(sound, sfx->mHandle, offset)) + { + mUnusedSounds.push_back(sound); + return nullptr; } - catch(std::exception&) + + if(sfx->mUses++ == 0) { - //std::cout <<"Sound Error: "<isInitialized()) return nullptr; - Sound *sound = nullptr; - try - { - // Look up the sound in the ESM data - Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId)); - float basevol = volumeFromType(type); - const ESM::Position &pos = ptr.getRefData().getPosition(); - const osg::Vec3f objpos(pos.asVec3()); - if((mode&Play_RemoveAtDistance) && (mListenerPos-objpos).length2() > 2000*2000) - return nullptr; + // Look up the sound in the ESM data + Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId)); + if(!sfx) return nullptr; - // Only one copy of given sound can be played at time on ptr, so stop previous copy - stopSound3D(ptr, soundId); + const osg::Vec3f objpos(ptr.getRefData().getPosition().asVec3()); + if((mode&Play_RemoveAtDistance) && (mListenerPos-objpos).length2() > 2000*2000) + return nullptr; - sound = getSoundRef(); - if(!(mode&Play_NoPlayerLocal) && ptr == MWMechanics::getPlayer()) - { - sound->init(volume * sfx->mVolume, basevol, pitch, mode|type|Play_2D); - mOutput->playSound(sound, sfx->mHandle, offset); - } - else - { - sound->init(objpos, volume * sfx->mVolume, basevol, pitch, - sfx->mMinDist, sfx->mMaxDist, mode|type|Play_3D); - mOutput->playSound3D(sound, sfx->mHandle, offset); - } - if(sfx->mUses++ == 0) - { - SoundList::iterator iter = std::find(mUnusedBuffers.begin(), mUnusedBuffers.end(), sfx); - if(iter != mUnusedBuffers.end()) - mUnusedBuffers.erase(iter); - } - mActiveSounds[ptr].push_back(std::make_pair(sound, sfx)); + // Only one copy of given sound can be played at time on ptr, so stop previous copy + stopSound3D(ptr, soundId); + + bool played; + Sound *sound = getSoundRef(); + if(!(mode&Play_NoPlayerLocal) && ptr == MWMechanics::getPlayer()) + { + sound->init(volume * sfx->mVolume, volumeFromType(type), pitch, mode|type|Play_2D); + played = mOutput->playSound(sound, sfx->mHandle, offset); } - catch(std::exception&) + else { - //std::cout <<"Sound Error: "<init(objpos, volume * sfx->mVolume, volumeFromType(type), pitch, + sfx->mMinDist, sfx->mMaxDist, mode|type|Play_3D); + played = mOutput->playSound3D(sound, sfx->mHandle, offset); } + if(!played) + { + mUnusedSounds.push_back(sound); + return nullptr; + } + + if(sfx->mUses++ == 0) + { + SoundList::iterator iter = std::find(mUnusedBuffers.begin(), mUnusedBuffers.end(), sfx); + if(iter != mUnusedBuffers.end()) + mUnusedBuffers.erase(iter); + } + mActiveSounds[ptr].push_back(std::make_pair(sound, sfx)); return sound; } @@ -657,32 +643,27 @@ namespace MWSound { if(!mOutput->isInitialized()) return nullptr; - Sound *sound = nullptr; - try - { - // Look up the sound in the ESM data - Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId)); - float basevol = volumeFromType(type); - sound = getSoundRef(); - sound->init(initialPos, volume * sfx->mVolume, basevol, pitch, - sfx->mMinDist, sfx->mMaxDist, mode|type|Play_3D); - mOutput->playSound3D(sound, sfx->mHandle, offset); - if(sfx->mUses++ == 0) - { - SoundList::iterator iter = std::find(mUnusedBuffers.begin(), mUnusedBuffers.end(), sfx); - if(iter != mUnusedBuffers.end()) - mUnusedBuffers.erase(iter); - } - mActiveSounds[MWWorld::ConstPtr()].push_back(std::make_pair(sound, sfx)); + // Look up the sound in the ESM data + Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId)); + if(!sfx) return nullptr; + + Sound *sound = getSoundRef(); + sound->init(initialPos, volume * sfx->mVolume, volumeFromType(type), pitch, + sfx->mMinDist, sfx->mMaxDist, mode|type|Play_3D); + if(!mOutput->playSound3D(sound, sfx->mHandle, offset)) + { + mUnusedSounds.push_back(sound); + return nullptr; } - catch(std::exception &) + + if(sfx->mUses++ == 0) { - //std::cout <<"Sound Error: "<