mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-27 03:35:27 +00:00
Use a separate map for say sounds
Also restores lip movement
This commit is contained in:
parent
9d0018e1bc
commit
3fdc3c4ea9
@ -92,6 +92,10 @@ namespace MWSound
|
|||||||
|
|
||||||
SoundManager::~SoundManager()
|
SoundManager::~SoundManager()
|
||||||
{
|
{
|
||||||
|
mUnderwaterSound.reset();
|
||||||
|
mActiveSounds.clear();
|
||||||
|
mActiveSaySounds.clear();
|
||||||
|
mMusic.reset();
|
||||||
if(mOutput->isInitialized())
|
if(mOutput->isInitialized())
|
||||||
{
|
{
|
||||||
NameBufferMap::iterator sfxiter = mSoundBuffers.begin();
|
NameBufferMap::iterator sfxiter = mSoundBuffers.begin();
|
||||||
@ -109,9 +113,6 @@ namespace MWSound
|
|||||||
sfxiter->second.mHandle = 0;
|
sfxiter->second.mHandle = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mUnderwaterSound.reset();
|
|
||||||
mActiveSounds.clear();
|
|
||||||
mMusic.reset();
|
|
||||||
mOutput.reset();
|
mOutput.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,21 +225,6 @@ namespace MWSound
|
|||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SoundManager::isPlaying(const MWWorld::Ptr &ptr, const std::string &id) const
|
|
||||||
{
|
|
||||||
SoundMap::const_iterator snditer = mActiveSounds.find(ptr);
|
|
||||||
if(snditer != mActiveSounds.end())
|
|
||||||
{
|
|
||||||
SoundNamePairList::const_iterator sndname = snditer->second.begin();
|
|
||||||
for(;sndname != snditer->second.end();++sndname)
|
|
||||||
{
|
|
||||||
if(sndname->second == id && sndname->first->isPlaying())
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SoundManager::stopMusic()
|
void SoundManager::stopMusic()
|
||||||
{
|
{
|
||||||
@ -325,13 +311,15 @@ namespace MWSound
|
|||||||
startRandomTitle();
|
startRandomTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SoundManager::say(const MWWorld::Ptr &ptr, const std::string &filename)
|
void SoundManager::say(const MWWorld::Ptr &ptr, const std::string &filename)
|
||||||
{
|
{
|
||||||
if(!mOutput->isInitialized())
|
if(!mOutput->isInitialized())
|
||||||
return;
|
return;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const Sound_Buffer *sfx = lookupVoice(Misc::StringUtils::lowerCase(filename));
|
std::string voicefile = Misc::StringUtils::lowerCase(filename);
|
||||||
|
const Sound_Buffer *sfx = lookupVoice(voicefile);
|
||||||
float basevol = volumeFromType(Play_TypeVoice);
|
float basevol = volumeFromType(Play_TypeVoice);
|
||||||
const ESM::Position &pos = ptr.getRefData().getPosition();
|
const ESM::Position &pos = ptr.getRefData().getPosition();
|
||||||
const osg::Vec3f objpos(pos.asVec3());
|
const osg::Vec3f objpos(pos.asVec3());
|
||||||
@ -339,7 +327,7 @@ namespace MWSound
|
|||||||
MWBase::SoundPtr sound = mOutput->playSound3D(sfx->mHandle,
|
MWBase::SoundPtr sound = mOutput->playSound3D(sfx->mHandle,
|
||||||
objpos, sfx->mVolume, basevol, 1.0f, sfx->mMinDist, sfx->mMaxDist, Play_Normal|Play_TypeVoice, 0
|
objpos, sfx->mVolume, basevol, 1.0f, sfx->mMinDist, sfx->mMaxDist, Play_Normal|Play_TypeVoice, 0
|
||||||
);
|
);
|
||||||
mActiveSounds[ptr].push_back(std::make_pair(sound, std::string("_say_sound")));
|
mActiveSaySounds[ptr] = std::make_pair(sound, voicefile);
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
@ -349,14 +337,15 @@ namespace MWSound
|
|||||||
|
|
||||||
float SoundManager::getSaySoundLoudness(const MWWorld::Ptr &ptr) const
|
float SoundManager::getSaySoundLoudness(const MWWorld::Ptr &ptr) const
|
||||||
{
|
{
|
||||||
SoundMap::const_iterator snditer = mActiveSounds.find(ptr);
|
SaySoundMap::const_iterator snditer = mActiveSaySounds.find(ptr);
|
||||||
if(snditer != mActiveSounds.end())
|
if(snditer != mActiveSaySounds.end())
|
||||||
{
|
{
|
||||||
SoundNamePairList::const_iterator sndname = snditer->second.begin();
|
NameBufferMap::const_iterator sfxiter = mVoiceSoundBuffers.find(snditer->second.second);
|
||||||
for(;sndname != snditer->second.end();++sndname)
|
if(sfxiter != mVoiceSoundBuffers.end())
|
||||||
{
|
{
|
||||||
if(sndname->second == "_say_sound")
|
float sec = snditer->second.first->getTimeOffset();
|
||||||
return 0.0f;
|
if(snditer->second.first->isPlaying())
|
||||||
|
return sfxiter->second.mLoudness.getLoudnessAtTime(sec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,13 +358,14 @@ namespace MWSound
|
|||||||
return;
|
return;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const Sound_Buffer *sfx = lookupVoice(Misc::StringUtils::lowerCase(filename));
|
std::string voicefile = Misc::StringUtils::lowerCase(filename);
|
||||||
|
const Sound_Buffer *sfx = lookupVoice(voicefile);
|
||||||
float basevol = volumeFromType(Play_TypeVoice);
|
float basevol = volumeFromType(Play_TypeVoice);
|
||||||
|
|
||||||
MWBase::SoundPtr sound = mOutput->playSound(sfx->mHandle,
|
MWBase::SoundPtr sound = mOutput->playSound(sfx->mHandle,
|
||||||
sfx->mVolume, basevol, 1.0f, Play_Normal|Play_TypeVoice, 0
|
sfx->mVolume, basevol, 1.0f, Play_Normal|Play_TypeVoice, 0
|
||||||
);
|
);
|
||||||
mActiveSounds[MWWorld::Ptr()].push_back(std::make_pair(sound, std::string("_say_sound")));
|
mActiveSaySounds[MWWorld::Ptr()] = std::make_pair(sound, voicefile);
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
@ -385,26 +375,22 @@ namespace MWSound
|
|||||||
|
|
||||||
bool SoundManager::sayDone(const MWWorld::Ptr &ptr) const
|
bool SoundManager::sayDone(const MWWorld::Ptr &ptr) const
|
||||||
{
|
{
|
||||||
return !isPlaying(ptr, "_say_sound");
|
SaySoundMap::const_iterator snditer = mActiveSaySounds.find(ptr);
|
||||||
|
if(snditer != mActiveSaySounds.end())
|
||||||
|
{
|
||||||
|
if(snditer->second.first->isPlaying())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundManager::stopSay(const MWWorld::Ptr &ptr)
|
void SoundManager::stopSay(const MWWorld::Ptr &ptr)
|
||||||
{
|
{
|
||||||
SoundMap::iterator snditer = mActiveSounds.find(ptr);
|
SaySoundMap::iterator snditer = mActiveSaySounds.find(ptr);
|
||||||
if(snditer != mActiveSounds.end())
|
if(snditer != mActiveSaySounds.end())
|
||||||
{
|
{
|
||||||
SoundNamePairList::iterator sndname = snditer->second.begin();
|
snditer->second.first->stop();
|
||||||
for(;sndname != snditer->second.end();++sndname)
|
mActiveSaySounds.erase(snditer);
|
||||||
{
|
|
||||||
if(sndname->second != "_say_sound")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
sndname->first->stop();
|
|
||||||
snditer->second.erase(sndname);
|
|
||||||
if(snditer->second.empty())
|
|
||||||
mActiveSounds.erase(snditer);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,6 +412,21 @@ namespace MWSound
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SoundManager::isPlaying(const MWWorld::Ptr &ptr, const std::string &id) const
|
||||||
|
{
|
||||||
|
SoundMap::const_iterator snditer = mActiveSounds.find(ptr);
|
||||||
|
if(snditer != mActiveSounds.end())
|
||||||
|
{
|
||||||
|
SoundNamePairList::const_iterator sndname = snditer->second.begin();
|
||||||
|
for(;sndname != snditer->second.end();++sndname)
|
||||||
|
{
|
||||||
|
if(sndname->second == id && sndname->first->isPlaying())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
MWBase::SoundPtr SoundManager::playSound(const std::string& soundId, float volume, float pitch, PlayType type, PlayMode mode, float offset)
|
MWBase::SoundPtr SoundManager::playSound(const std::string& soundId, float volume, float pitch, PlayType type, PlayMode mode, float offset)
|
||||||
{
|
{
|
||||||
MWBase::SoundPtr sound;
|
MWBase::SoundPtr sound;
|
||||||
@ -573,6 +574,19 @@ namespace MWSound
|
|||||||
else
|
else
|
||||||
++snditer;
|
++snditer;
|
||||||
}
|
}
|
||||||
|
SaySoundMap::iterator sayiter = mActiveSaySounds.begin();
|
||||||
|
while(sayiter != mActiveSaySounds.end())
|
||||||
|
{
|
||||||
|
if(sayiter->first != MWWorld::Ptr() &&
|
||||||
|
sayiter->first != MWMechanics::getPlayer() &&
|
||||||
|
sayiter->first.getCell() == cell)
|
||||||
|
{
|
||||||
|
sayiter->second.first->stop();
|
||||||
|
mActiveSaySounds.erase(sayiter++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++sayiter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundManager::stopSound(const std::string& soundId)
|
void SoundManager::stopSound(const std::string& soundId)
|
||||||
@ -740,7 +754,8 @@ namespace MWSound
|
|||||||
SoundNamePairList::iterator sndname = snditer->second.begin();
|
SoundNamePairList::iterator sndname = snditer->second.begin();
|
||||||
while(sndname != snditer->second.end())
|
while(sndname != snditer->second.end())
|
||||||
{
|
{
|
||||||
if(!sndname->first->isPlaying())
|
MWBase::SoundPtr sound = sndname->first;
|
||||||
|
if(!sound->isPlaying())
|
||||||
{
|
{
|
||||||
sndname = snditer->second.erase(sndname);
|
sndname = snditer->second.erase(sndname);
|
||||||
continue;
|
continue;
|
||||||
@ -751,9 +766,9 @@ namespace MWSound
|
|||||||
{
|
{
|
||||||
const ESM::Position &pos = ptr.getRefData().getPosition();
|
const ESM::Position &pos = ptr.getRefData().getPosition();
|
||||||
const osg::Vec3f objpos(pos.asVec3());
|
const osg::Vec3f objpos(pos.asVec3());
|
||||||
sndname->first->setPosition(objpos);
|
sound->setPosition(objpos);
|
||||||
|
|
||||||
if ((sndname->first->mFlags & Play_RemoveAtDistance)
|
if ((sound->mFlags & Play_RemoveAtDistance)
|
||||||
&& (mListenerPos - ptr.getRefData().getPosition().asVec3()).length2() > 2000*2000)
|
&& (mListenerPos - ptr.getRefData().getPosition().asVec3()).length2() > 2000*2000)
|
||||||
{
|
{
|
||||||
sndname = snditer->second.erase(sndname);
|
sndname = snditer->second.erase(sndname);
|
||||||
@ -762,16 +777,16 @@ namespace MWSound
|
|||||||
}
|
}
|
||||||
|
|
||||||
//update fade out
|
//update fade out
|
||||||
if(sndname->first->mFadeOutTime > 0.0f)
|
if(sound->mFadeOutTime > 0.0f)
|
||||||
{
|
{
|
||||||
float soundDuration = duration;
|
float soundDuration = duration;
|
||||||
if(soundDuration > sndname->first->mFadeOutTime)
|
if(soundDuration > sound->mFadeOutTime)
|
||||||
soundDuration = sndname->first->mFadeOutTime;
|
soundDuration = sound->mFadeOutTime;
|
||||||
sndname->first->setVolume(sndname->first->mVolume
|
sound->setVolume(sound->mVolume - soundDuration/sound->mFadeOutTime*sound->mVolume);
|
||||||
- soundDuration / sndname->first->mFadeOutTime * sndname->first->mVolume);
|
sound->mFadeOutTime -= soundDuration;
|
||||||
sndname->first->mFadeOutTime -= soundDuration;
|
|
||||||
}
|
}
|
||||||
sndname->first->update();
|
sound->update();
|
||||||
|
|
||||||
++sndname;
|
++sndname;
|
||||||
}
|
}
|
||||||
if(snditer->second.empty())
|
if(snditer->second.empty())
|
||||||
@ -779,6 +794,45 @@ namespace MWSound
|
|||||||
else
|
else
|
||||||
++snditer;
|
++snditer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SaySoundMap::iterator sayiter = mActiveSaySounds.begin();
|
||||||
|
while(sayiter != mActiveSaySounds.end())
|
||||||
|
{
|
||||||
|
MWBase::SoundPtr sound = sayiter->second.first;
|
||||||
|
if(!sound->isPlaying())
|
||||||
|
{
|
||||||
|
mActiveSaySounds.erase(sayiter++);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MWWorld::Ptr &ptr = sayiter->first;
|
||||||
|
if(!ptr.isEmpty())
|
||||||
|
{
|
||||||
|
const ESM::Position &pos = ptr.getRefData().getPosition();
|
||||||
|
const osg::Vec3f objpos(pos.asVec3());
|
||||||
|
sound->setPosition(objpos);
|
||||||
|
|
||||||
|
if ((sound->mFlags & Play_RemoveAtDistance)
|
||||||
|
&& (mListenerPos - ptr.getRefData().getPosition().asVec3()).length2() > 2000*2000)
|
||||||
|
{
|
||||||
|
mActiveSaySounds.erase(sayiter++);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//update fade out
|
||||||
|
if(sound->mFadeOutTime > 0.0f)
|
||||||
|
{
|
||||||
|
float soundDuration = duration;
|
||||||
|
if(soundDuration > sound->mFadeOutTime)
|
||||||
|
soundDuration = sound->mFadeOutTime;
|
||||||
|
sound->setVolume(sound->mVolume - soundDuration/sound->mFadeOutTime*sound->mVolume);
|
||||||
|
sound->mFadeOutTime -= soundDuration;
|
||||||
|
}
|
||||||
|
sound->update();
|
||||||
|
|
||||||
|
++sayiter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundManager::update(float duration)
|
void SoundManager::update(float duration)
|
||||||
@ -841,6 +895,13 @@ namespace MWSound
|
|||||||
mActiveSounds.erase(snditer);
|
mActiveSounds.erase(snditer);
|
||||||
mActiveSounds[updated] = sndlist;
|
mActiveSounds[updated] = sndlist;
|
||||||
}
|
}
|
||||||
|
SaySoundMap::iterator sayiter = mActiveSaySounds.find(old);
|
||||||
|
if(sayiter != mActiveSaySounds.end())
|
||||||
|
{
|
||||||
|
SoundNamePair sndlist = sayiter->second;
|
||||||
|
mActiveSaySounds.erase(sayiter);
|
||||||
|
mActiveSaySounds[updated] = sndlist;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default readAll implementation, for decoders that can't do anything
|
// Default readAll implementation, for decoders that can't do anything
|
||||||
@ -918,6 +979,10 @@ namespace MWSound
|
|||||||
sndname->first->stop();
|
sndname->first->stop();
|
||||||
}
|
}
|
||||||
mActiveSounds.clear();
|
mActiveSounds.clear();
|
||||||
|
SaySoundMap::iterator sayiter = mActiveSaySounds.begin();
|
||||||
|
for(;sayiter != mActiveSaySounds.end();++sayiter)
|
||||||
|
sayiter->second.first->stop();
|
||||||
|
mActiveSaySounds.clear();
|
||||||
stopMusic();
|
stopMusic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,9 @@ namespace MWSound
|
|||||||
typedef std::map<MWWorld::Ptr,SoundNamePairList> SoundMap;
|
typedef std::map<MWWorld::Ptr,SoundNamePairList> SoundMap;
|
||||||
SoundMap mActiveSounds;
|
SoundMap mActiveSounds;
|
||||||
|
|
||||||
|
typedef std::map<MWWorld::Ptr,SoundNamePair> SaySoundMap;
|
||||||
|
SaySoundMap mActiveSaySounds;
|
||||||
|
|
||||||
MWBase::SoundPtr mUnderwaterSound;
|
MWBase::SoundPtr mUnderwaterSound;
|
||||||
|
|
||||||
bool mListenerUnderwater;
|
bool mListenerUnderwater;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user