1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-23 10:20:48 +00:00

Replace some shared_ptrs with pointers to deque entries

This commit is contained in:
Chris Robinson 2017-09-11 21:33:18 -07:00
parent bd667c3847
commit 1fe60dd8e2
12 changed files with 260 additions and 175 deletions

View File

@ -22,8 +22,8 @@ namespace MWSound
namespace MWBase namespace MWBase
{ {
typedef std::shared_ptr<MWSound::Sound> SoundPtr; using Sound = MWSound::Sound;
typedef std::shared_ptr<MWSound::Stream> SoundStreamPtr; using SoundStream = MWSound::Stream;
/// \brief Interface for sound manager (implemented in MWSound) /// \brief Interface for sound manager (implemented in MWSound)
class SoundManager class SoundManager
@ -106,34 +106,35 @@ namespace MWBase
/// and get an average loudness value (scale [0,1]) at the current time position. /// and get an average loudness value (scale [0,1]) at the current time position.
/// If the actor is not saying anything, returns 0. /// If the actor is not saying anything, returns 0.
virtual SoundStreamPtr playTrack(const MWSound::DecoderPtr& decoder, PlayType type) = 0; virtual SoundStream *playTrack(const MWSound::DecoderPtr& decoder, PlayType type) = 0;
///< Play a 2D audio track, using a custom decoder ///< Play a 2D audio track, using a custom decoder
virtual void stopTrack(SoundStreamPtr stream) = 0; virtual void stopTrack(SoundStream *stream) = 0;
///< Stop the given audio track from playing ///< Stop the given audio track from playing
virtual double getTrackTimeDelay(SoundStreamPtr stream) = 0; virtual double getTrackTimeDelay(SoundStream *stream) = 0;
///< Retives the time delay, in seconds, of the audio track (must be a sound ///< Retives the time delay, in seconds, of the audio track (must be a sound
/// returned by \ref playTrack). Only intended to be called by the track /// returned by \ref playTrack). Only intended to be called by the track
/// decoder's read method. /// decoder's read method.
virtual SoundPtr playSound(const std::string& soundId, float volume, float pitch, virtual Sound *playSound(const std::string& soundId, float volume, float pitch,
PlayType type=Play_TypeSfx, PlayMode mode=Play_Normal, PlayType type=Play_TypeSfx, PlayMode mode=Play_Normal,
float offset=0) = 0; float offset=0) = 0;
///< Play a sound, independently of 3D-position ///< Play a sound, independently of 3D-position
///< @param offset Number of seconds into the sound to start playback. ///< @param offset Number of seconds into the sound to start playback.
virtual MWBase::SoundPtr playSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId, virtual Sound *playSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId,
float volume, float pitch, PlayType type=Play_TypeSfx, float volume, float pitch, PlayType type=Play_TypeSfx,
PlayMode mode=Play_Normal, float offset=0) = 0; PlayMode mode=Play_Normal, float offset=0) = 0;
///< Play a 3D sound attached to an MWWorld::Ptr. Will be updated automatically with the Ptr's position, unless Play_NoTrack is specified. ///< Play a 3D sound attached to an MWWorld::Ptr. Will be updated automatically with the Ptr's position, unless Play_NoTrack is specified.
///< @param offset Number of seconds into the sound to start playback. ///< @param offset Number of seconds into the sound to start playback.
virtual MWBase::SoundPtr playSound3D(const osg::Vec3f& initialPos, const std::string& soundId, virtual Sound *playSound3D(const osg::Vec3f& initialPos, const std::string& soundId,
float volume, float pitch, PlayType type=Play_TypeSfx, PlayMode mode=Play_Normal, float offset=0) = 0; float volume, float pitch, PlayType type=Play_TypeSfx,
PlayMode mode=Play_Normal, float offset=0) = 0;
///< Play a 3D sound at \a initialPos. If the sound should be moving, it must be updated using Sound::setPosition. ///< Play a 3D sound at \a initialPos. If the sound should be moving, it must be updated using Sound::setPosition.
virtual void stopSound(SoundPtr sound) = 0; virtual void stopSound(Sound *sound) = 0;
///< Stop the given sound from playing ///< Stop the given sound from playing
virtual void stopSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId) = 0; virtual void stopSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId) = 0;

View File

@ -37,7 +37,7 @@ namespace MWSound
{ {
public: public:
MovieAudioDecoder(Video::VideoState *videoState) MovieAudioDecoder(Video::VideoState *videoState)
: Video::MovieAudioDecoder(videoState) : Video::MovieAudioDecoder(videoState), mAudioTrack(nullptr)
{ {
mDecoderBridge.reset(new MWSoundDecoderBridge(this)); mDecoderBridge.reset(new MWSoundDecoderBridge(this));
} }
@ -85,13 +85,13 @@ namespace MWSound
public: public:
~MovieAudioDecoder() ~MovieAudioDecoder()
{ {
if(mAudioTrack.get()) if(mAudioTrack)
MWBase::Environment::get().getSoundManager()->stopTrack(mAudioTrack); MWBase::Environment::get().getSoundManager()->stopTrack(mAudioTrack);
mAudioTrack.reset(); mAudioTrack = nullptr;
mDecoderBridge.reset(); mDecoderBridge.reset();
} }
MWBase::SoundStreamPtr mAudioTrack; MWBase::SoundStream *mAudioTrack;
std::shared_ptr<MWSoundDecoderBridge> mDecoderBridge; std::shared_ptr<MWSoundDecoderBridge> mDecoderBridge;
}; };
@ -162,8 +162,8 @@ namespace MWSound
decoder->setupFormat(); decoder->setupFormat();
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
MWBase::SoundStreamPtr sound = sndMgr->playTrack(decoder->mDecoderBridge, MWBase::SoundManager::Play_TypeMovie); MWBase::SoundStream *sound = sndMgr->playTrack(decoder->mDecoderBridge, MWBase::SoundManager::Play_TypeMovie);
if (!sound.get()) if (!sound)
{ {
decoder.reset(); decoder.reset();
return decoder; return decoder;

View File

@ -841,7 +841,7 @@ void OpenAL_Output::updateCommon(ALuint source, const osg::Vec3f& pos, ALfloat m
} }
void OpenAL_Output::playSound(MWBase::SoundPtr sound, Sound_Handle data, float offset) void OpenAL_Output::playSound(Sound *sound, Sound_Handle data, float offset)
{ {
ALuint source; ALuint source;
@ -871,7 +871,7 @@ void OpenAL_Output::playSound(MWBase::SoundPtr sound, Sound_Handle data, float o
sound->mHandle = MAKE_PTRID(source); sound->mHandle = MAKE_PTRID(source);
} }
void OpenAL_Output::playSound3D(MWBase::SoundPtr sound, Sound_Handle data, float offset) void OpenAL_Output::playSound3D(Sound *sound, Sound_Handle data, float offset)
{ {
ALuint source; ALuint source;
@ -902,7 +902,7 @@ void OpenAL_Output::playSound3D(MWBase::SoundPtr sound, Sound_Handle data, float
sound->mHandle = MAKE_PTRID(source); sound->mHandle = MAKE_PTRID(source);
} }
void OpenAL_Output::finishSound(MWBase::SoundPtr sound) void OpenAL_Output::finishSound(Sound *sound)
{ {
if(!sound->mHandle) return; if(!sound->mHandle) return;
ALuint source = GET_PTRID(sound->mHandle); ALuint source = GET_PTRID(sound->mHandle);
@ -918,7 +918,7 @@ void OpenAL_Output::finishSound(MWBase::SoundPtr sound)
mActiveSounds.erase(std::find(mActiveSounds.begin(), mActiveSounds.end(), sound)); mActiveSounds.erase(std::find(mActiveSounds.begin(), mActiveSounds.end(), sound));
} }
bool OpenAL_Output::isSoundPlaying(MWBase::SoundPtr sound) bool OpenAL_Output::isSoundPlaying(Sound *sound)
{ {
if(!sound->mHandle) return false; if(!sound->mHandle) return false;
ALuint source = GET_PTRID(sound->mHandle); ALuint source = GET_PTRID(sound->mHandle);
@ -930,7 +930,7 @@ bool OpenAL_Output::isSoundPlaying(MWBase::SoundPtr sound)
return state == AL_PLAYING || state == AL_PAUSED; return state == AL_PLAYING || state == AL_PAUSED;
} }
void OpenAL_Output::updateSound(MWBase::SoundPtr sound) void OpenAL_Output::updateSound(Sound *sound)
{ {
if(!sound->mHandle) return; if(!sound->mHandle) return;
ALuint source = GET_PTRID(sound->mHandle); ALuint source = GET_PTRID(sound->mHandle);
@ -940,7 +940,7 @@ void OpenAL_Output::updateSound(MWBase::SoundPtr sound)
} }
void OpenAL_Output::streamSound(DecoderPtr decoder, MWBase::SoundStreamPtr sound) void OpenAL_Output::streamSound(DecoderPtr decoder, Stream *sound)
{ {
OpenAL_SoundStream *stream = 0; OpenAL_SoundStream *stream = 0;
ALuint source; ALuint source;
@ -971,7 +971,7 @@ void OpenAL_Output::streamSound(DecoderPtr decoder, MWBase::SoundStreamPtr sound
sound->mHandle = stream; sound->mHandle = stream;
} }
void OpenAL_Output::streamSound3D(DecoderPtr decoder, MWBase::SoundStreamPtr sound, bool getLoudnessData) void OpenAL_Output::streamSound3D(DecoderPtr decoder, Stream *sound, bool getLoudnessData)
{ {
OpenAL_SoundStream *stream = 0; OpenAL_SoundStream *stream = 0;
ALuint source; ALuint source;
@ -1002,7 +1002,7 @@ void OpenAL_Output::streamSound3D(DecoderPtr decoder, MWBase::SoundStreamPtr sou
sound->mHandle = stream; sound->mHandle = stream;
} }
void OpenAL_Output::finishStream(MWBase::SoundStreamPtr sound) void OpenAL_Output::finishStream(Stream *sound)
{ {
if(!sound->mHandle) return; if(!sound->mHandle) return;
OpenAL_SoundStream *stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle); OpenAL_SoundStream *stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle);
@ -1023,14 +1023,14 @@ void OpenAL_Output::finishStream(MWBase::SoundStreamPtr sound)
delete stream; delete stream;
} }
double OpenAL_Output::getStreamDelay(MWBase::SoundStreamPtr sound) double OpenAL_Output::getStreamDelay(Stream *sound)
{ {
if(!sound->mHandle) return 0.0; if(!sound->mHandle) return 0.0;
OpenAL_SoundStream *stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle); OpenAL_SoundStream *stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle);
return stream->getStreamDelay(); return stream->getStreamDelay();
} }
double OpenAL_Output::getStreamOffset(MWBase::SoundStreamPtr sound) double OpenAL_Output::getStreamOffset(Stream *sound)
{ {
if(!sound->mHandle) return 0.0; if(!sound->mHandle) return 0.0;
OpenAL_SoundStream *stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle); OpenAL_SoundStream *stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle);
@ -1038,7 +1038,7 @@ double OpenAL_Output::getStreamOffset(MWBase::SoundStreamPtr sound)
return stream->getStreamOffset(); return stream->getStreamOffset();
} }
float OpenAL_Output::getStreamLoudness(MWBase::SoundStreamPtr sound) float OpenAL_Output::getStreamLoudness(Stream *sound)
{ {
if(!sound->mHandle) return 0.0; if(!sound->mHandle) return 0.0;
OpenAL_SoundStream *stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle); OpenAL_SoundStream *stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle);
@ -1046,7 +1046,7 @@ float OpenAL_Output::getStreamLoudness(MWBase::SoundStreamPtr sound)
return stream->getCurrentLoudness(); return stream->getCurrentLoudness();
} }
bool OpenAL_Output::isStreamPlaying(MWBase::SoundStreamPtr sound) bool OpenAL_Output::isStreamPlaying(Stream *sound)
{ {
if(!sound->mHandle) return false; if(!sound->mHandle) return false;
OpenAL_SoundStream *stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle); OpenAL_SoundStream *stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle);
@ -1054,7 +1054,7 @@ bool OpenAL_Output::isStreamPlaying(MWBase::SoundStreamPtr sound)
return stream->isPlaying(); return stream->isPlaying();
} }
void OpenAL_Output::updateStream(MWBase::SoundStreamPtr sound) void OpenAL_Output::updateStream(Stream *sound)
{ {
if(!sound->mHandle) return; if(!sound->mHandle) return;
OpenAL_SoundStream *stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle); OpenAL_SoundStream *stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle);

View File

@ -15,6 +15,7 @@ namespace MWSound
{ {
class SoundManager; class SoundManager;
class Sound; class Sound;
class Stream;
class OpenAL_Output : public Sound_Output class OpenAL_Output : public Sound_Output
{ {
@ -24,9 +25,9 @@ namespace MWSound
typedef std::deque<ALuint> IDDq; typedef std::deque<ALuint> IDDq;
IDDq mFreeSources; IDDq mFreeSources;
typedef std::vector<MWBase::SoundPtr> SoundVec; typedef std::vector<Sound*> SoundVec;
SoundVec mActiveSounds; SoundVec mActiveSounds;
typedef std::vector<MWBase::SoundStreamPtr> StreamVec; typedef std::vector<Stream*> StreamVec;
StreamVec mActiveStreams; StreamVec mActiveStreams;
osg::Vec3f mListenerPos; osg::Vec3f mListenerPos;
@ -56,20 +57,20 @@ namespace MWSound
virtual void unloadSound(Sound_Handle data); virtual void unloadSound(Sound_Handle data);
virtual size_t getSoundDataSize(Sound_Handle data) const; virtual size_t getSoundDataSize(Sound_Handle data) const;
virtual void playSound(MWBase::SoundPtr sound, Sound_Handle data, float offset); virtual void playSound(Sound *sound, Sound_Handle data, float offset);
virtual void playSound3D(MWBase::SoundPtr sound, Sound_Handle data, float offset); virtual void playSound3D(Sound *sound, Sound_Handle data, float offset);
virtual void finishSound(MWBase::SoundPtr sound); virtual void finishSound(Sound *sound);
virtual bool isSoundPlaying(MWBase::SoundPtr sound); virtual bool isSoundPlaying(Sound *sound);
virtual void updateSound(MWBase::SoundPtr sound); virtual void updateSound(Sound *sound);
virtual void streamSound(DecoderPtr decoder, MWBase::SoundStreamPtr sound); virtual void streamSound(DecoderPtr decoder, Stream *sound);
virtual void streamSound3D(DecoderPtr decoder, MWBase::SoundStreamPtr sound, bool getLoudnessData); virtual void streamSound3D(DecoderPtr decoder, Stream *sound, bool getLoudnessData);
virtual void finishStream(MWBase::SoundStreamPtr sound); virtual void finishStream(Stream *sound);
virtual double getStreamDelay(MWBase::SoundStreamPtr sound); virtual double getStreamDelay(Stream *sound);
virtual double getStreamOffset(MWBase::SoundStreamPtr sound); virtual double getStreamOffset(Stream *sound);
virtual float getStreamLoudness(MWBase::SoundStreamPtr sound); virtual float getStreamLoudness(Stream *sound);
virtual bool isStreamPlaying(MWBase::SoundStreamPtr sound); virtual bool isStreamPlaying(Stream *sound);
virtual void updateStream(MWBase::SoundStreamPtr sound); virtual void updateStream(Stream *sound);
virtual void startUpdate(); virtual void startUpdate();
virtual void finishUpdate(); virtual void finishUpdate();

View File

@ -54,15 +54,36 @@ namespace MWSound
bool getDistanceCull() const { return mFlags&MWBase::SoundManager::Play_RemoveAtDistance; } bool getDistanceCull() const { return mFlags&MWBase::SoundManager::Play_RemoveAtDistance; }
bool getIs3D() const { return mFlags&Play_3D; } bool getIs3D() const { return mFlags&Play_3D; }
Sound(const osg::Vec3f& pos, float vol, float basevol, float pitch, float mindist, float maxdist, int flags) void init(const osg::Vec3f& pos, float vol, float basevol, float pitch, float mindist, float maxdist, int flags)
: mPos(pos), mVolume(vol), mBaseVolume(basevol), mPitch(pitch) {
, mMinDistance(mindist), mMaxDistance(maxdist), mFlags(flags) mPos = pos;
, mFadeOutTime(0.0f), mHandle(0) mVolume = vol;
{ } mBaseVolume = basevol;
Sound(float vol, float basevol, float pitch, int flags) mPitch = pitch;
: mPos(0.0f, 0.0f, 0.0f), mVolume(vol), mBaseVolume(basevol), mPitch(pitch) mMinDistance = mindist;
, mMinDistance(1.0f), mMaxDistance(1000.0f), mFlags(flags) mMaxDistance = maxdist;
, mFadeOutTime(0.0f), mHandle(0) mFlags = flags;
mFadeOutTime = 0.0f;
mHandle = nullptr;
}
void init(float vol, float basevol, float pitch, int flags)
{
mPos = osg::Vec3f(0.0f, 0.0f, 0.0f);
mVolume = vol;
mBaseVolume = basevol;
mPitch = pitch;
mMinDistance = 1.0f;
mMaxDistance = 1000.0f;
mFlags = flags;
mFadeOutTime = 0.0f;
mHandle = nullptr;
}
Sound()
: mPos(0.0f, 0.0f, 0.0f), mVolume(1.0f), mBaseVolume(1.0f), mPitch(1.0f)
, mMinDistance(1.0f), mMaxDistance(1000.0f), mFlags(0), mFadeOutTime(0.0f)
, mHandle(0)
{ } { }
}; };
@ -72,12 +93,7 @@ namespace MWSound
Stream(const Stream &rhs); Stream(const Stream &rhs);
public: public:
Stream(const osg::Vec3f& pos, float vol, float basevol, float pitch, float mindist, float maxdist, int flags) Stream() { }
: Sound(pos, vol, basevol, pitch, mindist, maxdist, flags)
{ }
Stream(float vol, float basevol, float pitch, int flags)
: Sound(vol, basevol, pitch, flags)
{ }
}; };
} }

View File

@ -12,6 +12,7 @@ namespace MWSound
class SoundManager; class SoundManager;
struct Sound_Decoder; struct Sound_Decoder;
class Sound; class Sound;
class Stream;
// An opaque handle for the implementation's sound buffers. // An opaque handle for the implementation's sound buffers.
typedef void *Sound_Handle; typedef void *Sound_Handle;
@ -34,20 +35,20 @@ namespace MWSound
virtual void unloadSound(Sound_Handle data) = 0; virtual void unloadSound(Sound_Handle data) = 0;
virtual size_t getSoundDataSize(Sound_Handle data) const = 0; virtual size_t getSoundDataSize(Sound_Handle data) const = 0;
virtual void playSound(MWBase::SoundPtr sound, Sound_Handle data, float offset) = 0; virtual void playSound(Sound *sound, Sound_Handle data, float offset) = 0;
virtual void playSound3D(MWBase::SoundPtr sound, Sound_Handle data, float offset) = 0; virtual void playSound3D(Sound *sound, Sound_Handle data, float offset) = 0;
virtual void finishSound(MWBase::SoundPtr sound) = 0; virtual void finishSound(Sound *sound) = 0;
virtual bool isSoundPlaying(MWBase::SoundPtr sound) = 0; virtual bool isSoundPlaying(Sound *sound) = 0;
virtual void updateSound(MWBase::SoundPtr sound) = 0; virtual void updateSound(Sound *sound) = 0;
virtual void streamSound(DecoderPtr decoder, MWBase::SoundStreamPtr sound) = 0; virtual void streamSound(DecoderPtr decoder, Stream *sound) = 0;
virtual void streamSound3D(DecoderPtr decoder, MWBase::SoundStreamPtr sound, bool getLoudnessData) = 0; virtual void streamSound3D(DecoderPtr decoder, Stream *sound, bool getLoudnessData) = 0;
virtual void finishStream(MWBase::SoundStreamPtr sound) = 0; virtual void finishStream(Stream *sound) = 0;
virtual double getStreamDelay(MWBase::SoundStreamPtr sound) = 0; virtual double getStreamDelay(Stream *sound) = 0;
virtual double getStreamOffset(MWBase::SoundStreamPtr sound) = 0; virtual double getStreamOffset(Stream *sound) = 0;
virtual float getStreamLoudness(MWBase::SoundStreamPtr sound) = 0; virtual float getStreamLoudness(Stream *sound) = 0;
virtual bool isStreamPlaying(MWBase::SoundStreamPtr sound) = 0; virtual bool isStreamPlaying(Stream *sound) = 0;
virtual void updateStream(MWBase::SoundStreamPtr sound) = 0; virtual void updateStream(Stream *sound) = 0;
virtual void startUpdate() = 0; virtual void startUpdate() = 0;
virtual void finishUpdate() = 0; virtual void finishUpdate() = 0;

View File

@ -46,11 +46,16 @@ namespace MWSound
, mFootstepsVolume(1.0f) , mFootstepsVolume(1.0f)
, mSoundBuffers(new SoundBufferList::element_type()) , mSoundBuffers(new SoundBufferList::element_type())
, mBufferCacheSize(0) , mBufferCacheSize(0)
, mSounds(new std::deque<Sound>())
, mStreams(new std::deque<Stream>())
, mMusic(nullptr)
, mListenerUnderwater(false) , mListenerUnderwater(false)
, mListenerPos(0,0,0) , mListenerPos(0,0,0)
, mListenerDir(1,0,0) , mListenerDir(1,0,0)
, mListenerUp(0,0,1) , mListenerUp(0,0,1)
, mPausedSoundTypes(0) , mPausedSoundTypes(0)
, mUnderwaterSound(nullptr)
, mNearWaterSound(nullptr)
{ {
mMasterVolume = Settings::Manager::getFloat("master volume", "Sound"); mMasterVolume = Settings::Manager::getFloat("master volume", "Sound");
mMasterVolume = std::min(std::max(mMasterVolume, 0.0f), 1.0f); mMasterVolume = std::min(std::max(mMasterVolume, 0.0f), 1.0f);
@ -246,7 +251,39 @@ namespace MWSound
return decoder; return decoder;
} }
MWBase::SoundStreamPtr SoundManager::playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal) Sound *SoundManager::getSoundRef()
{
Sound *ret;
if(!mUnusedSounds.empty())
{
ret = mUnusedSounds.back();
mUnusedSounds.pop_back();
}
else
{
mSounds->emplace_back();
ret = &mSounds->back();
}
return ret;
}
Stream *SoundManager::getStreamRef()
{
Stream *ret;
if(!mUnusedStreams.empty())
{
ret = mUnusedStreams.back();
mUnusedStreams.pop_back();
}
else
{
mStreams->emplace_back();
ret = &mStreams->back();
}
return ret;
}
Stream *SoundManager::playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal)
{ {
MWBase::World* world = MWBase::Environment::get().getWorld(); MWBase::World* world = MWBase::Environment::get().getWorld();
static const float fAudioMinDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMinDistanceMult")->getFloat(); static const float fAudioMinDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMinDistanceMult")->getFloat();
@ -256,17 +293,17 @@ namespace MWSound
static float minDistance = std::max(fAudioVoiceDefaultMinDistance * fAudioMinDistanceMult, 1.0f); static float minDistance = std::max(fAudioVoiceDefaultMinDistance * fAudioMinDistanceMult, 1.0f);
static float maxDistance = std::max(fAudioVoiceDefaultMaxDistance * fAudioMaxDistanceMult, minDistance); static float maxDistance = std::max(fAudioVoiceDefaultMaxDistance * fAudioMaxDistanceMult, minDistance);
MWBase::SoundStreamPtr sound;
float basevol = volumeFromType(Play_TypeVoice); float basevol = volumeFromType(Play_TypeVoice);
Stream *sound = getStreamRef();
if(playlocal) if(playlocal)
{ {
sound.reset(new Stream(1.0f, basevol, 1.0f, Play_NoEnv|Play_TypeVoice|Play_2D)); sound->init(1.0f, basevol, 1.0f, Play_NoEnv|Play_TypeVoice|Play_2D);
mOutput->streamSound(decoder, sound); mOutput->streamSound(decoder, sound);
} }
else else
{ {
sound.reset(new Stream(pos, 1.0f, basevol, 1.0f, minDistance, maxDistance, sound->init(pos, 1.0f, basevol, 1.0f, minDistance, maxDistance,
Play_Normal|Play_TypeVoice|Play_3D)); Play_Normal|Play_TypeVoice|Play_3D);
mOutput->streamSound3D(decoder, sound, true); mOutput->streamSound3D(decoder, sound, true);
} }
return sound; return sound;
@ -301,8 +338,11 @@ namespace MWSound
void SoundManager::stopMusic() void SoundManager::stopMusic()
{ {
if(mMusic) if(mMusic)
{
mOutput->finishStream(mMusic); mOutput->finishStream(mMusic);
mMusic.reset(); mUnusedStreams.push_back(mMusic);
mMusic = nullptr;
}
} }
void SoundManager::streamMusicFull(const std::string& filename) void SoundManager::streamMusicFull(const std::string& filename)
@ -317,13 +357,16 @@ namespace MWSound
DecoderPtr decoder = getDecoder(); DecoderPtr decoder = getDecoder();
decoder->open(filename); decoder->open(filename);
mMusic.reset(new Stream(1.0f, volumeFromType(Play_TypeMusic), 1.0f, mMusic = getStreamRef();
Play_NoEnv|Play_TypeMusic|Play_2D)); mMusic->init(1.0f, volumeFromType(Play_TypeMusic), 1.0f,
Play_NoEnv|Play_TypeMusic|Play_2D);
mOutput->streamSound(decoder, mMusic); mOutput->streamSound(decoder, mMusic);
} }
catch(std::exception &e) { catch(std::exception &e) {
std::cout << "Music Error: " << e.what() << "\n"; std::cout << "Music Error: " << e.what() << "\n";
mMusic.reset(); if(mMusic)
mUnusedStreams.push_back(mMusic);
mMusic = nullptr;
} }
} }
@ -421,15 +464,8 @@ namespace MWSound
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
const osg::Vec3f pos = world->getActorHeadTransform(ptr).getTrans(); const osg::Vec3f pos = world->getActorHeadTransform(ptr).getTrans();
SaySoundMap::iterator oldIt = mActiveSaySounds.find(ptr); stopSay(ptr);
if (oldIt != mActiveSaySounds.end()) Stream *sound = playVoice(decoder, pos, (ptr == MWMechanics::getPlayer()));
{
mOutput->finishStream(oldIt->second);
mActiveSaySounds.erase(oldIt);
}
MWBase::SoundStreamPtr sound = playVoice(decoder, pos, (ptr == MWMechanics::getPlayer()));
mActiveSaySounds.insert(std::make_pair(ptr, sound)); mActiveSaySounds.insert(std::make_pair(ptr, sound));
} }
catch(std::exception &e) catch(std::exception &e)
@ -443,7 +479,7 @@ namespace MWSound
SaySoundMap::const_iterator snditer = mActiveSaySounds.find(ptr); SaySoundMap::const_iterator snditer = mActiveSaySounds.find(ptr);
if(snditer != mActiveSaySounds.end()) if(snditer != mActiveSaySounds.end())
{ {
MWBase::SoundStreamPtr sound = snditer->second; Stream *sound = snditer->second;
return mOutput->getStreamLoudness(sound); return mOutput->getStreamLoudness(sound);
} }
@ -461,13 +497,7 @@ namespace MWSound
mVFS->normalizeFilename(voicefile); mVFS->normalizeFilename(voicefile);
DecoderPtr decoder = loadVoice(voicefile); DecoderPtr decoder = loadVoice(voicefile);
SaySoundMap::iterator oldIt = mActiveSaySounds.find(MWWorld::ConstPtr()); stopSay(MWWorld::ConstPtr());
if (oldIt != mActiveSaySounds.end())
{
mOutput->finishStream(oldIt->second);
mActiveSaySounds.erase(oldIt);
}
mActiveSaySounds.insert(std::make_pair(MWWorld::ConstPtr(), mActiveSaySounds.insert(std::make_pair(MWWorld::ConstPtr(),
playVoice(decoder, osg::Vec3f(), true))); playVoice(decoder, osg::Vec3f(), true)));
} }
@ -495,19 +525,20 @@ namespace MWSound
if(snditer != mActiveSaySounds.end()) if(snditer != mActiveSaySounds.end())
{ {
mOutput->finishStream(snditer->second); mOutput->finishStream(snditer->second);
mUnusedStreams.push_back(snditer->second);
mActiveSaySounds.erase(snditer); mActiveSaySounds.erase(snditer);
} }
} }
MWBase::SoundStreamPtr SoundManager::playTrack(const DecoderPtr& decoder, PlayType type) Stream *SoundManager::playTrack(const DecoderPtr& decoder, PlayType type)
{ {
MWBase::SoundStreamPtr track;
if(!mOutput->isInitialized()) if(!mOutput->isInitialized())
return track; return nullptr;
Stream *track = getStreamRef();
try try
{ {
track.reset(new Stream(1.0f, volumeFromType(type), 1.0f, Play_NoEnv|type|Play_2D)); track->init(1.0f, volumeFromType(type), 1.0f, Play_NoEnv|type|Play_2D);
mOutput->streamSound(decoder, track); mOutput->streamSound(decoder, track);
TrackList::iterator iter = std::lower_bound(mActiveTracks.begin(), mActiveTracks.end(), track); TrackList::iterator iter = std::lower_bound(mActiveTracks.begin(), mActiveTracks.end(), track);
@ -516,35 +547,40 @@ namespace MWSound
catch(std::exception &e) catch(std::exception &e)
{ {
std::cout <<"Sound Error: "<<e.what()<< std::endl; std::cout <<"Sound Error: "<<e.what()<< std::endl;
if(track)
mUnusedStreams.push_back(track);
track = nullptr;
} }
return track; return track;
} }
void SoundManager::stopTrack(MWBase::SoundStreamPtr stream) void SoundManager::stopTrack(Stream *stream)
{ {
mOutput->finishStream(stream); mOutput->finishStream(stream);
TrackList::iterator iter = std::lower_bound(mActiveTracks.begin(), mActiveTracks.end(), stream); TrackList::iterator iter = std::lower_bound(mActiveTracks.begin(), mActiveTracks.end(), stream);
if(iter != mActiveTracks.end() && *iter == stream) if(iter != mActiveTracks.end() && *iter == stream)
mActiveTracks.erase(iter); mActiveTracks.erase(iter);
mUnusedStreams.push_back(stream);
} }
double SoundManager::getTrackTimeDelay(MWBase::SoundStreamPtr stream) double SoundManager::getTrackTimeDelay(Stream *stream)
{ {
return mOutput->getStreamDelay(stream); return mOutput->getStreamDelay(stream);
} }
MWBase::SoundPtr SoundManager::playSound(const std::string& soundId, float volume, float pitch, PlayType type, PlayMode mode, float offset) Sound *SoundManager::playSound(const std::string& soundId, float volume, float pitch, PlayType type, PlayMode mode, float offset)
{ {
MWBase::SoundPtr sound;
if(!mOutput->isInitialized()) if(!mOutput->isInitialized())
return sound; return nullptr;
Sound *sound = nullptr;
try try
{ {
Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId)); Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId));
float basevol = volumeFromType(type); float basevol = volumeFromType(type);
sound.reset(new Sound(volume * sfx->mVolume, basevol, pitch, mode|type|Play_2D)); sound = getSoundRef();
sound->init(volume * sfx->mVolume, basevol, pitch, mode|type|Play_2D);
mOutput->playSound(sound, sfx->mHandle, offset); mOutput->playSound(sound, sfx->mHandle, offset);
if(sfx->mUses++ == 0) if(sfx->mUses++ == 0)
{ {
@ -557,17 +593,20 @@ namespace MWSound
catch(std::exception&) catch(std::exception&)
{ {
//std::cout <<"Sound Error: "<<e.what()<< std::endl; //std::cout <<"Sound Error: "<<e.what()<< std::endl;
sound.reset(); if(sound)
mUnusedSounds.push_back(sound);
sound = nullptr;
} }
return sound; return sound;
} }
MWBase::SoundPtr SoundManager::playSound3D(const MWWorld::ConstPtr &ptr, const std::string& soundId, Sound *SoundManager::playSound3D(const MWWorld::ConstPtr &ptr, const std::string& soundId,
float volume, float pitch, PlayType type, PlayMode mode, float offset) float volume, float pitch, PlayType type, PlayMode mode,
float offset)
{ {
MWBase::SoundPtr sound;
if(!mOutput->isInitialized()) if(!mOutput->isInitialized())
return sound; return nullptr;
Sound *sound = nullptr;
try try
{ {
// Look up the sound in the ESM data // Look up the sound in the ESM data
@ -577,20 +616,21 @@ namespace MWSound
const osg::Vec3f objpos(pos.asVec3()); const osg::Vec3f objpos(pos.asVec3());
if((mode&Play_RemoveAtDistance) && (mListenerPos-objpos).length2() > 2000*2000) if((mode&Play_RemoveAtDistance) && (mListenerPos-objpos).length2() > 2000*2000)
return MWBase::SoundPtr(); return nullptr;
// Only one copy of given sound can be played at time on ptr, so stop previous copy // Only one copy of given sound can be played at time on ptr, so stop previous copy
stopSound3D(ptr, soundId); stopSound3D(ptr, soundId);
sound = getSoundRef();
if(!(mode&Play_NoPlayerLocal) && ptr == MWMechanics::getPlayer()) if(!(mode&Play_NoPlayerLocal) && ptr == MWMechanics::getPlayer())
{ {
sound.reset(new Sound(volume * sfx->mVolume, basevol, pitch, mode|type|Play_2D)); sound->init(volume * sfx->mVolume, basevol, pitch, mode|type|Play_2D);
mOutput->playSound(sound, sfx->mHandle, offset); mOutput->playSound(sound, sfx->mHandle, offset);
} }
else else
{ {
sound.reset(new Sound(objpos, volume * sfx->mVolume, basevol, pitch, sound->init(objpos, volume * sfx->mVolume, basevol, pitch,
sfx->mMinDist, sfx->mMaxDist, mode|type|Play_3D)); sfx->mMinDist, sfx->mMaxDist, mode|type|Play_3D);
mOutput->playSound3D(sound, sfx->mHandle, offset); mOutput->playSound3D(sound, sfx->mHandle, offset);
} }
if(sfx->mUses++ == 0) if(sfx->mUses++ == 0)
@ -604,25 +644,29 @@ namespace MWSound
catch(std::exception&) catch(std::exception&)
{ {
//std::cout <<"Sound Error: "<<e.what()<< std::endl; //std::cout <<"Sound Error: "<<e.what()<< std::endl;
sound.reset(); if(sound)
mUnusedSounds.push_back(sound);
sound = nullptr;
} }
return sound; return sound;
} }
MWBase::SoundPtr SoundManager::playSound3D(const osg::Vec3f& initialPos, const std::string& soundId, Sound *SoundManager::playSound3D(const osg::Vec3f& initialPos, const std::string& soundId,
float volume, float pitch, PlayType type, PlayMode mode, float offset) float volume, float pitch, PlayType type, PlayMode mode,
float offset)
{ {
MWBase::SoundPtr sound;
if(!mOutput->isInitialized()) if(!mOutput->isInitialized())
return sound; return nullptr;
Sound *sound = nullptr;
try try
{ {
// Look up the sound in the ESM data // Look up the sound in the ESM data
Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId)); Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId));
float basevol = volumeFromType(type); float basevol = volumeFromType(type);
sound.reset(new Sound(initialPos, volume * sfx->mVolume, basevol, pitch, sound = getSoundRef();
sfx->mMinDist, sfx->mMaxDist, mode|type|Play_3D)); sound->init(initialPos, volume * sfx->mVolume, basevol, pitch,
sfx->mMinDist, sfx->mMaxDist, mode|type|Play_3D);
mOutput->playSound3D(sound, sfx->mHandle, offset); mOutput->playSound3D(sound, sfx->mHandle, offset);
if(sfx->mUses++ == 0) if(sfx->mUses++ == 0)
{ {
@ -635,14 +679,16 @@ namespace MWSound
catch(std::exception &) catch(std::exception &)
{ {
//std::cout <<"Sound Error: "<<e.what()<< std::endl; //std::cout <<"Sound Error: "<<e.what()<< std::endl;
sound.reset(); if(sound)
mUnusedSounds.push_back(sound);
sound = nullptr;
} }
return sound; return sound;
} }
void SoundManager::stopSound(MWBase::SoundPtr sound) void SoundManager::stopSound(Sound *sound)
{ {
if (sound.get()) if(sound)
mOutput->finishSound(sound); mOutput->finishSound(sound);
} }
@ -675,7 +721,7 @@ namespace MWSound
void SoundManager::stopSound(const MWWorld::CellStore *cell) void SoundManager::stopSound(const MWWorld::CellStore *cell)
{ {
SoundMap::iterator snditer = mActiveSounds.begin(); SoundMap::iterator snditer = mActiveSounds.begin();
while(snditer != mActiveSounds.end()) for(;snditer != mActiveSounds.end();++snditer)
{ {
if(snditer->first != MWWorld::ConstPtr() && if(snditer->first != MWWorld::ConstPtr() &&
snditer->first != MWMechanics::getPlayer() && snditer->first != MWMechanics::getPlayer() &&
@ -685,19 +731,15 @@ namespace MWSound
for(;sndidx != snditer->second.end();++sndidx) for(;sndidx != snditer->second.end();++sndidx)
mOutput->finishSound(sndidx->first); mOutput->finishSound(sndidx->first);
} }
++snditer;
} }
SaySoundMap::iterator sayiter = mActiveSaySounds.begin(); SaySoundMap::iterator sayiter = mActiveSaySounds.begin();
while(sayiter != mActiveSaySounds.end()) for(;sayiter != mActiveSaySounds.end();++sayiter)
{ {
if(sayiter->first != MWWorld::ConstPtr() && if(sayiter->first != MWWorld::ConstPtr() &&
sayiter->first != MWMechanics::getPlayer() && sayiter->first != MWMechanics::getPlayer() &&
sayiter->first.getCell() == cell) sayiter->first.getCell() == cell)
{
mOutput->finishStream(sayiter->second); mOutput->finishStream(sayiter->second);
} }
++sayiter;
}
} }
void SoundManager::stopSound(const std::string& soundId) void SoundManager::stopSound(const std::string& soundId)
@ -885,7 +927,7 @@ namespace MWSound
if (volume == 0.0f) if (volume == 0.0f)
{ {
mOutput->finishSound(mNearWaterSound); mOutput->finishSound(mNearWaterSound);
mNearWaterSound.reset(); mNearWaterSound = nullptr;
} }
else else
{ {
@ -939,7 +981,7 @@ namespace MWSound
else if(mUnderwaterSound) else if(mUnderwaterSound)
{ {
mOutput->finishSound(mUnderwaterSound); mOutput->finishSound(mUnderwaterSound);
mUnderwaterSound.reset(); mUnderwaterSound = nullptr;
} }
mOutput->startUpdate(); mOutput->startUpdate();
@ -960,7 +1002,7 @@ namespace MWSound
while(sndidx != snditer->second.end()) while(sndidx != snditer->second.end())
{ {
MWWorld::ConstPtr ptr = snditer->first; MWWorld::ConstPtr ptr = snditer->first;
MWBase::SoundPtr sound = sndidx->first; Sound *sound = sndidx->first;
if(!ptr.isEmpty() && sound->getIs3D()) if(!ptr.isEmpty() && sound->getIs3D())
{ {
const ESM::Position &pos = ptr.getRefData().getPosition(); const ESM::Position &pos = ptr.getRefData().getPosition();
@ -977,6 +1019,11 @@ namespace MWSound
if(!mOutput->isSoundPlaying(sound)) if(!mOutput->isSoundPlaying(sound))
{ {
mOutput->finishSound(sound); mOutput->finishSound(sound);
mUnusedSounds.push_back(sound);
if(sound == mUnderwaterSound)
mUnderwaterSound = nullptr;
if(sound == mNearWaterSound)
mNearWaterSound = nullptr;
Sound_Buffer *sfx = sndidx->second; Sound_Buffer *sfx = sndidx->second;
if(sfx->mUses-- == 1) if(sfx->mUses-- == 1)
mUnusedBuffers.push_front(sfx); mUnusedBuffers.push_front(sfx);
@ -1000,7 +1047,7 @@ namespace MWSound
while(sayiter != mActiveSaySounds.end()) while(sayiter != mActiveSaySounds.end())
{ {
MWWorld::ConstPtr ptr = sayiter->first; MWWorld::ConstPtr ptr = sayiter->first;
MWBase::SoundStreamPtr sound = sayiter->second; Stream *sound = sayiter->second;
if(!ptr.isEmpty() && sound->getIs3D()) if(!ptr.isEmpty() && sound->getIs3D())
{ {
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
@ -1017,6 +1064,7 @@ namespace MWSound
if(!mOutput->isStreamPlaying(sound)) if(!mOutput->isStreamPlaying(sound))
{ {
mOutput->finishStream(sound); mOutput->finishStream(sound);
mUnusedStreams.push_back(sound);
mActiveSaySounds.erase(sayiter++); mActiveSaySounds.erase(sayiter++);
} }
else else
@ -1031,10 +1079,11 @@ namespace MWSound
TrackList::iterator trkiter = mActiveTracks.begin(); TrackList::iterator trkiter = mActiveTracks.begin();
for(;trkiter != mActiveTracks.end();++trkiter) for(;trkiter != mActiveTracks.end();++trkiter)
{ {
MWBase::SoundStreamPtr sound = *trkiter; Stream *sound = *trkiter;
if(!mOutput->isStreamPlaying(sound)) if(!mOutput->isStreamPlaying(sound))
{ {
mOutput->finishStream(sound); mOutput->finishStream(sound);
mUnusedStreams.push_back(sound);
trkiter = mActiveTracks.erase(trkiter); trkiter = mActiveTracks.erase(trkiter);
} }
else else
@ -1049,7 +1098,7 @@ namespace MWSound
if(mListenerUnderwater) if(mListenerUnderwater)
{ {
// Play underwater sound (after updating sounds) // Play underwater sound (after updating sounds)
if(!(mUnderwaterSound && mOutput->isSoundPlaying(mUnderwaterSound))) if(!mUnderwaterSound)
mUnderwaterSound = playSound("Underwater", 1.0f, 1.0f, Play_TypeSfx, Play_LoopNoEnv); mUnderwaterSound = playSound("Underwater", 1.0f, 1.0f, Play_TypeSfx, Play_LoopNoEnv);
} }
mOutput->finishUpdate(); mOutput->finishUpdate();
@ -1105,7 +1154,7 @@ namespace MWSound
SoundBufferRefPairList::iterator sndidx = snditer->second.begin(); SoundBufferRefPairList::iterator sndidx = snditer->second.begin();
for(;sndidx != snditer->second.end();++sndidx) for(;sndidx != snditer->second.end();++sndidx)
{ {
MWBase::SoundPtr sound = sndidx->first; Sound *sound = sndidx->first;
sound->setBaseVolume(volumeFromType(sound->getPlayType())); sound->setBaseVolume(volumeFromType(sound->getPlayType()));
mOutput->updateSound(sound); mOutput->updateSound(sound);
} }
@ -1113,14 +1162,14 @@ namespace MWSound
SaySoundMap::iterator sayiter = mActiveSaySounds.begin(); SaySoundMap::iterator sayiter = mActiveSaySounds.begin();
for(;sayiter != mActiveSaySounds.end();++sayiter) for(;sayiter != mActiveSaySounds.end();++sayiter)
{ {
MWBase::SoundStreamPtr sound = sayiter->second; Stream *sound = sayiter->second;
sound->setBaseVolume(volumeFromType(sound->getPlayType())); sound->setBaseVolume(volumeFromType(sound->getPlayType()));
mOutput->updateStream(sound); mOutput->updateStream(sound);
} }
TrackList::iterator trkiter = mActiveTracks.begin(); TrackList::iterator trkiter = mActiveTracks.begin();
for(;trkiter != mActiveTracks.end();++trkiter) for(;trkiter != mActiveTracks.end();++trkiter)
{ {
MWBase::SoundStreamPtr sound = *trkiter; Stream *sound = *trkiter;
sound->setBaseVolume(volumeFromType(sound->getPlayType())); sound->setBaseVolume(volumeFromType(sound->getPlayType()));
mOutput->updateStream(sound); mOutput->updateStream(sound);
} }
@ -1153,7 +1202,7 @@ namespace MWSound
SaySoundMap::iterator sayiter = mActiveSaySounds.find(old); SaySoundMap::iterator sayiter = mActiveSaySounds.find(old);
if(sayiter != mActiveSaySounds.end()) if(sayiter != mActiveSaySounds.end())
{ {
MWBase::SoundStreamPtr stream = sayiter->second; Stream *stream = sayiter->second;
mActiveSaySounds.erase(sayiter); mActiveSaySounds.erase(sayiter);
mActiveSaySounds[updated] = stream; mActiveSaySounds[updated] = stream;
} }
@ -1233,6 +1282,7 @@ namespace MWSound
for(;sndidx != snditer->second.end();++sndidx) for(;sndidx != snditer->second.end();++sndidx)
{ {
mOutput->finishSound(sndidx->first); mOutput->finishSound(sndidx->first);
mUnusedSounds.push_back(sndidx->first);
Sound_Buffer *sfx = sndidx->second; Sound_Buffer *sfx = sndidx->second;
if(sfx->mUses-- == 1) if(sfx->mUses-- == 1)
mUnusedBuffers.push_front(sfx); mUnusedBuffers.push_front(sfx);
@ -1241,14 +1291,20 @@ namespace MWSound
mActiveSounds.clear(); mActiveSounds.clear();
SaySoundMap::iterator sayiter = mActiveSaySounds.begin(); SaySoundMap::iterator sayiter = mActiveSaySounds.begin();
for(;sayiter != mActiveSaySounds.end();++sayiter) for(;sayiter != mActiveSaySounds.end();++sayiter)
{
mOutput->finishStream(sayiter->second); mOutput->finishStream(sayiter->second);
mUnusedStreams.push_back(sayiter->second);
}
mActiveSaySounds.clear(); mActiveSaySounds.clear();
TrackList::iterator trkiter = mActiveTracks.begin(); TrackList::iterator trkiter = mActiveTracks.begin();
for(;trkiter != mActiveTracks.end();++trkiter) for(;trkiter != mActiveTracks.end();++trkiter)
{
mOutput->finishStream(*trkiter); mOutput->finishStream(*trkiter);
mUnusedStreams.push_back(*trkiter);
}
mActiveTracks.clear(); mActiveTracks.clear();
mUnderwaterSound.reset(); mUnderwaterSound = nullptr;
mNearWaterSound.reset(); mNearWaterSound = nullptr;
stopMusic(); stopMusic();
} }
} }

View File

@ -29,6 +29,7 @@ namespace MWSound
class Sound_Output; class Sound_Output;
struct Sound_Decoder; struct Sound_Decoder;
class Sound; class Sound;
class Stream;
class Sound_Buffer; class Sound_Buffer;
enum Environment { enum Environment {
@ -81,18 +82,24 @@ namespace MWSound
typedef std::deque<Sound_Buffer*> SoundList; typedef std::deque<Sound_Buffer*> SoundList;
SoundList mUnusedBuffers; SoundList mUnusedBuffers;
typedef std::pair<MWBase::SoundPtr,Sound_Buffer*> SoundBufferRefPair; std::unique_ptr<std::deque<Sound>> mSounds;
std::vector<Sound*> mUnusedSounds;
std::unique_ptr<std::deque<Stream>> mStreams;
std::vector<Stream*> mUnusedStreams;
typedef std::pair<MWBase::Sound*,Sound_Buffer*> SoundBufferRefPair;
typedef std::vector<SoundBufferRefPair> SoundBufferRefPairList; typedef std::vector<SoundBufferRefPair> SoundBufferRefPairList;
typedef std::map<MWWorld::ConstPtr,SoundBufferRefPairList> SoundMap; typedef std::map<MWWorld::ConstPtr,SoundBufferRefPairList> SoundMap;
SoundMap mActiveSounds; SoundMap mActiveSounds;
typedef std::map<MWWorld::ConstPtr,MWBase::SoundStreamPtr> SaySoundMap; typedef std::map<MWWorld::ConstPtr,Stream*> SaySoundMap;
SaySoundMap mActiveSaySounds; SaySoundMap mActiveSaySounds;
typedef std::vector<MWBase::SoundStreamPtr> TrackList; typedef std::vector<Stream*> TrackList;
TrackList mActiveTracks; TrackList mActiveTracks;
MWBase::SoundStreamPtr mMusic; Stream *mMusic;
std::string mCurrentPlaylist; std::string mCurrentPlaylist;
bool mListenerUnderwater; bool mListenerUnderwater;
@ -102,8 +109,8 @@ namespace MWSound
int mPausedSoundTypes; int mPausedSoundTypes;
MWBase::SoundPtr mUnderwaterSound; Sound *mUnderwaterSound;
MWBase::SoundPtr mNearWaterSound; Sound *mNearWaterSound;
Sound_Buffer *insertSound(const std::string &soundId, const ESM::Sound *sound); Sound_Buffer *insertSound(const std::string &soundId, const ESM::Sound *sound);
@ -113,7 +120,10 @@ namespace MWSound
// returns a decoder to start streaming // returns a decoder to start streaming
DecoderPtr loadVoice(const std::string &voicefile); DecoderPtr loadVoice(const std::string &voicefile);
MWBase::SoundStreamPtr playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal); Sound *getSoundRef();
Stream *getStreamRef();
Stream *playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal);
void streamMusicFull(const std::string& filename); void streamMusicFull(const std::string& filename);
void advanceMusic(const std::string& filename); void advanceMusic(const std::string& filename);
@ -176,33 +186,33 @@ namespace MWSound
/// and get an average loudness value (scale [0,1]) at the current time position. /// and get an average loudness value (scale [0,1]) at the current time position.
/// If the actor is not saying anything, returns 0. /// If the actor is not saying anything, returns 0.
virtual MWBase::SoundStreamPtr playTrack(const DecoderPtr& decoder, PlayType type); virtual Stream *playTrack(const DecoderPtr& decoder, PlayType type);
///< Play a 2D audio track, using a custom decoder ///< Play a 2D audio track, using a custom decoder
virtual void stopTrack(MWBase::SoundStreamPtr stream); virtual void stopTrack(Stream *stream);
///< Stop the given audio track from playing ///< Stop the given audio track from playing
virtual double getTrackTimeDelay(MWBase::SoundStreamPtr stream); virtual double getTrackTimeDelay(Stream *stream);
///< Retives the time delay, in seconds, of the audio track (must be a sound ///< Retives the time delay, in seconds, of the audio track (must be a sound
/// returned by \ref playTrack). Only intended to be called by the track /// returned by \ref playTrack). Only intended to be called by the track
/// decoder's read method. /// decoder's read method.
virtual MWBase::SoundPtr playSound(const std::string& soundId, float volume, float pitch, PlayType type=Play_TypeSfx, PlayMode mode=Play_Normal, float offset=0); virtual Sound *playSound(const std::string& soundId, float volume, float pitch, PlayType type=Play_TypeSfx, PlayMode mode=Play_Normal, float offset=0);
///< Play a sound, independently of 3D-position ///< Play a sound, independently of 3D-position
///< @param offset Number of seconds into the sound to start playback. ///< @param offset Number of seconds into the sound to start playback.
virtual MWBase::SoundPtr playSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId, virtual Sound *playSound3D(const MWWorld::ConstPtr &reference, const std::string& soundId,
float volume, float pitch, PlayType type=Play_TypeSfx, float volume, float pitch, PlayType type=Play_TypeSfx,
PlayMode mode=Play_Normal, float offset=0); PlayMode mode=Play_Normal, float offset=0);
///< Play a 3D sound attached to an MWWorld::Ptr. Will be updated automatically with the Ptr's position, unless Play_NoTrack is specified. ///< Play a 3D sound attached to an MWWorld::Ptr. Will be updated automatically with the Ptr's position, unless Play_NoTrack is specified.
///< @param offset Number of seconds into the sound to start playback. ///< @param offset Number of seconds into the sound to start playback.
virtual MWBase::SoundPtr playSound3D(const osg::Vec3f& initialPos, const std::string& soundId, virtual Sound *playSound3D(const osg::Vec3f& initialPos, const std::string& soundId,
float volume, float pitch, PlayType type, PlayMode mode, float offset=0); float volume, float pitch, PlayType type, PlayMode mode, float offset=0);
///< Play a 3D sound at \a initialPos. If the sound should be moving, it must be updated using Sound::setPosition. ///< Play a 3D sound at \a initialPos. If the sound should be moving, it must be updated using Sound::setPosition.
///< @param offset Number of seconds into the sound to start playback. ///< @param offset Number of seconds into the sound to start playback.
virtual void stopSound(MWBase::SoundPtr sound); virtual void stopSound(Sound *sound);
///< Stop the given sound from playing ///< Stop the given sound from playing
/// @note no-op if \a sound is null /// @note no-op if \a sound is null

View File

@ -283,7 +283,7 @@ namespace MWWorld
MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager();
for (size_t it = 0; it != state.mSoundIds.size(); it++) for (size_t it = 0; it != state.mSoundIds.size(); it++)
{ {
MWBase::SoundPtr sound = sndMgr->playSound3D(pos, state.mSoundIds.at(it), 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop); MWBase::Sound *sound = sndMgr->playSound3D(pos, state.mSoundIds.at(it), 1.0f, 1.0f, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop);
if (sound) if (sound)
state.mSounds.push_back(sound); state.mSounds.push_back(sound);
} }
@ -584,7 +584,7 @@ namespace MWWorld
for (size_t soundIter = 0; soundIter != state.mSoundIds.size(); soundIter++) for (size_t soundIter = 0; soundIter != state.mSoundIds.size(); soundIter++)
{ {
MWBase::SoundPtr sound = sndMgr->playSound3D(esm.mPosition, state.mSoundIds.at(soundIter), 1.0f, 1.0f, MWBase::Sound *sound = sndMgr->playSound3D(esm.mPosition, state.mSoundIds.at(soundIter), 1.0f, 1.0f,
MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop); MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop);
if (sound) if (sound)
state.mSounds.push_back(sound); state.mSounds.push_back(sound);

View File

@ -103,7 +103,7 @@ namespace MWWorld
bool mStack; bool mStack;
std::vector<MWBase::SoundPtr> mSounds; std::vector<MWBase::Sound*> mSounds;
std::vector<std::string> mSoundIds; std::vector<std::string> mSoundIds;
}; };

View File

@ -531,7 +531,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager& rendering, const Fall
, mQueuedWeather(0) , mQueuedWeather(0)
, mRegions() , mRegions()
, mResult() , mResult()
, mAmbientSound() , mAmbientSound(nullptr)
, mPlayingSoundID() , mPlayingSoundID()
{ {
mTimeSettings.mNightStart = mSunsetTime + mSunsetDuration; mTimeSettings.mNightStart = mSunsetTime + mSunsetDuration;
@ -735,15 +735,15 @@ void WeatherManager::update(float duration, bool paused)
mPlayingSoundID = mResult.mAmbientLoopSoundID; mPlayingSoundID = mResult.mAmbientLoopSoundID;
} }
if (mAmbientSound.get()) else if (mAmbientSound)
mAmbientSound->setVolume(mResult.mAmbientSoundVolume); mAmbientSound->setVolume(mResult.mAmbientSoundVolume);
} }
void WeatherManager::stopSounds() void WeatherManager::stopSounds()
{ {
if (mAmbientSound.get()) if (mAmbientSound)
MWBase::Environment::get().getSoundManager()->stopSound(mAmbientSound); MWBase::Environment::get().getSoundManager()->stopSound(mAmbientSound);
mAmbientSound.reset(); mAmbientSound = nullptr;
mPlayingSoundID.clear(); mPlayingSoundID.clear();
} }

View File

@ -288,7 +288,7 @@ namespace MWWorld
std::map<std::string, RegionWeather> mRegions; std::map<std::string, RegionWeather> mRegions;
MWRender::WeatherResult mResult; MWRender::WeatherResult mResult;
MWBase::SoundPtr mAmbientSound; MWBase::Sound *mAmbientSound;
std::string mPlayingSoundID; std::string mPlayingSoundID;
void addWeather(const std::string& name, void addWeather(const std::string& name,