Old door sound fades out on door open/close. Door sound is synchronised to angle on action.

actorid
PLkolek 12 years ago
parent 0923306404
commit f297c21e4d

@ -103,13 +103,16 @@ namespace MWBase
///< Play a 2D audio track, using a custom decoder
virtual SoundPtr playSound(const std::string& soundId, float volume, float pitch,
PlayType type=Play_TypeSfx, PlayMode mode=Play_Normal) = 0;
PlayType type=Play_TypeSfx, PlayMode mode=Play_Normal,
float offset=0) = 0;
///< Play a sound, independently of 3D-position
///< @param offset Value from [0,1] meaning from which fraction the sound the playback starts.
virtual SoundPtr playSound3D(const MWWorld::Ptr &reference, const std::string& soundId,
float volume, float pitch, PlayType type=Play_TypeSfx,
PlayMode mode=Play_Normal) = 0;
PlayMode mode=Play_Normal, float offset=0) = 0;
///< Play a sound from an object
///< @param offset Value from [0,1] meaning from which fraction the sound the playback starts.
virtual void stopSound3D(const MWWorld::Ptr &reference, const std::string& soundId) = 0;
///< Stop the given object from playing the given sound,
@ -123,6 +126,12 @@ namespace MWBase
virtual void stopSound(const std::string& soundId) = 0;
///< Stop a non-3d looping sound
virtual void fadeOutSound3D(const MWWorld::Ptr &reference, const std::string& soundId, float duration) = 0;
///< Fade out given sound (that is already playing) of given object
///< @param reference Reference to object, whose sound is faded out
///< @param soundId ID of the sound to fade out.
///< @param duration Time until volume reaches 0.
virtual bool getSoundPlaying(const MWWorld::Ptr &reference, const std::string& soundId) const = 0;
///< Is the given sound currently playing on the given object?

@ -6,6 +6,7 @@
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/ptr.hpp"
@ -142,9 +143,23 @@ namespace MWClass
// animated door
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionDoor(ptr));
if (MWBase::Environment::get().getWorld()->getOpenOrCloseDoor(ptr))
{
MWBase::Environment::get().getSoundManager()->fadeOutSound3D(ptr,
closeSound, 0.5);
float offset = ptr.getRefData().getLocalRotation().rot[2]/ 3.14159265 * 2.0;
action->setSoundOffset(offset);
action->setSound(openSound);
}
else
{
MWBase::Environment::get().getSoundManager()->fadeOutSound3D(ptr,
openSound, 0.5);
float offset = 1.0 - ptr.getRefData().getLocalRotation().rot[2]/ 3.14159265 * 2.0;
//most if not all door have closing bang somewhere in the middle of the sound,
//so we divide offset by two
action->setSoundOffset(offset * 0.5);
action->setSound(closeSound);
}
return action;
}

@ -491,6 +491,7 @@ public:
virtual void stop();
virtual bool isPlaying();
virtual double getTimeOffset();
virtual double getLength();
virtual void update();
};
@ -554,6 +555,17 @@ double OpenAL_Sound::getTimeOffset()
return t;
}
double OpenAL_Sound::getLength()
{
ALint bufferSize, frequency, channels, bitsPerSample;
alGetBufferi(mBuffer, AL_SIZE, &bufferSize);
alGetBufferi(mBuffer, AL_FREQUENCY, &frequency);
alGetBufferi(mBuffer, AL_CHANNELS, &channels);
alGetBufferi(mBuffer, AL_BITS, &bitsPerSample);
return (8.0*bufferSize)/(frequency*channels*bitsPerSample);
}
void OpenAL_Sound::updateAll(bool local)
{
alSourcef(mSource, AL_REFERENCE_DISTANCE, mMinDistance);
@ -817,8 +829,7 @@ void OpenAL_Output::bufferFinished(ALuint buf)
}
}
MWBase::SoundPtr OpenAL_Output::playSound(const std::string &fname, float vol, float basevol, float pitch, int flags)
MWBase::SoundPtr OpenAL_Output::playSound(const std::string &fname, float vol, float basevol, float pitch, int flags,float offset)
{
boost::shared_ptr<OpenAL_Sound> sound;
ALuint src=0, buf=0;
@ -843,8 +854,13 @@ MWBase::SoundPtr OpenAL_Output::playSound(const std::string &fname, float vol, f
}
sound->updateAll(true);
if(offset<0)
offset=0;
if(offset>1)
offset=1;
alSourcei(src, AL_BUFFER, buf);
alSourcef(src, AL_SEC_OFFSET, sound->getLength()*offset/pitch);
alSourcePlay(src);
throwALerror();
@ -852,7 +868,7 @@ MWBase::SoundPtr OpenAL_Output::playSound(const std::string &fname, float vol, f
}
MWBase::SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const Ogre::Vector3 &pos, float vol, float basevol, float pitch,
float min, float max, int flags)
float min, float max, int flags, float offset)
{
boost::shared_ptr<OpenAL_Sound> sound;
ALuint src=0, buf=0;
@ -878,7 +894,14 @@ MWBase::SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const Ogre
sound->updateAll(false);
if(offset<0)
offset=0;
if(offset>1)
offset=1;
alSourcei(src, AL_BUFFER, buf);
alSourcef(src, AL_SEC_OFFSET, sound->getLength()*offset/pitch);
alSourcePlay(src);
throwALerror();

@ -45,9 +45,11 @@ namespace MWSound
virtual void init(const std::string &devname="");
virtual void deinit();
virtual MWBase::SoundPtr playSound(const std::string &fname, float vol, float basevol, float pitch, int flags);
/// @param offset Value from [0,1] meaning from which fraction the sound the playback starts.
virtual MWBase::SoundPtr playSound(const std::string &fname, float vol, float basevol, float pitch, int flags, float offset);
/// @param offset Value from [0,1] meaning from which fraction the sound the playback starts.
virtual MWBase::SoundPtr playSound3D(const std::string &fname, const Ogre::Vector3 &pos,
float vol, float basevol, float pitch, float min, float max, int flags);
float vol, float basevol, float pitch, float min, float max, int flags, float offset);
virtual MWBase::SoundPtr streamSound(DecoderPtr decoder, float volume, float pitch, int flags);
virtual void updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir, Environment env);

@ -22,6 +22,7 @@ namespace MWSound
float mMinDistance;
float mMaxDistance;
int mFlags;
float mFadeOutTime;
public:
virtual void stop() = 0;
@ -29,7 +30,7 @@ namespace MWSound
virtual double getTimeOffset() = 0;
void setPosition(const Ogre::Vector3 &pos) { mPos = pos; }
void setVolume(float volume) { mVolume = volume; }
void setFadeout(float duration) { mFadeOutTime=duration; }
MWBase::SoundManager::PlayType getPlayType() const
{ return (MWBase::SoundManager::PlayType)(mFlags&MWBase::SoundManager::Play_TypeMask); }
@ -42,6 +43,7 @@ namespace MWSound
, mMinDistance(mindist)
, mMaxDistance(maxdist)
, mFlags(flags)
, mFadeOutTime(0)
{ }
virtual ~Sound() { }

@ -24,9 +24,11 @@ namespace MWSound
virtual void init(const std::string &devname="") = 0;
virtual void deinit() = 0;
virtual MWBase::SoundPtr playSound(const std::string &fname, float vol, float basevol, float pitch, int flags) = 0;
/// @param offset Value from [0,1] meaning from which fraction the sound the playback starts.
virtual MWBase::SoundPtr playSound(const std::string &fname, float vol, float basevol, float pitch, int flags, float offset) = 0;
/// @param offset Value from [0,1] meaning from which fraction the sound the playback starts.
virtual MWBase::SoundPtr playSound3D(const std::string &fname, const Ogre::Vector3 &pos,
float vol, float basevol, float pitch, float min, float max, int flags) = 0;
float vol, float basevol, float pitch, float min, float max, int flags, float offset) = 0;
virtual MWBase::SoundPtr streamSound(DecoderPtr decoder, float volume, float pitch, int flags) = 0;
virtual void updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir, Environment env) = 0;

@ -255,7 +255,7 @@ namespace MWSound
const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]);
MWBase::SoundPtr sound = mOutput->playSound3D(filePath, objpos, 1.0f, basevol, 1.0f,
20.0f, 12750.0f, Play_Normal|Play_TypeVoice);
20.0f, 12750.0f, Play_Normal|Play_TypeVoice, 0);
mActiveSounds[sound] = std::make_pair(ptr, std::string("_say_sound"));
}
catch(std::exception &e)
@ -273,7 +273,7 @@ namespace MWSound
float basevol = volumeFromType(Play_TypeVoice);
std::string filePath = "Sound/"+filename;
MWBase::SoundPtr sound = mOutput->playSound(filePath, 1.0f, basevol, 1.0f, Play_Normal|Play_TypeVoice);
MWBase::SoundPtr sound = mOutput->playSound(filePath, 1.0f, basevol, 1.0f, Play_Normal|Play_TypeVoice, 0);
mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), std::string("_say_sound"));
}
catch(std::exception &e)
@ -320,7 +320,7 @@ namespace MWSound
}
MWBase::SoundPtr SoundManager::playSound(const std::string& soundId, float volume, float pitch, PlayType type, PlayMode mode)
MWBase::SoundPtr SoundManager::playSound(const std::string& soundId, float volume, float pitch, PlayType type, PlayMode mode, float offset)
{
MWBase::SoundPtr sound;
if(!mOutput->isInitialized())
@ -331,7 +331,7 @@ namespace MWSound
float min, max;
std::string file = lookup(soundId, volume, min, max);
sound = mOutput->playSound(file, volume, basevol, pitch, mode|type);
sound = mOutput->playSound(file, volume, basevol, pitch, mode|type, offset);
mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), soundId);
}
catch(std::exception &e)
@ -342,7 +342,7 @@ namespace MWSound
}
MWBase::SoundPtr SoundManager::playSound3D(const MWWorld::Ptr &ptr, const std::string& soundId,
float volume, float pitch, PlayType type, PlayMode mode)
float volume, float pitch, PlayType type, PlayMode mode, float offset)
{
MWBase::SoundPtr sound;
if(!mOutput->isInitialized())
@ -353,10 +353,10 @@ namespace MWSound
float basevol = volumeFromType(type);
float min, max;
std::string file = lookup(soundId, volume, min, max);
const ESM::Position &pos = ptr.getRefData().getPosition();;
const ESM::Position &pos = ptr.getRefData().getPosition();
const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]);
sound = mOutput->playSound3D(file, objpos, volume, basevol, pitch, min, max, mode|type);
sound = mOutput->playSound3D(file, objpos, volume, basevol, pitch, min, max, mode|type, offset);
if((mode&Play_NoTrack))
mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), soundId);
else
@ -431,6 +431,20 @@ namespace MWSound
}
}
void SoundManager::fadeOutSound3D(const MWWorld::Ptr &ptr,
const std::string& soundId, float duration)
{
SoundMap::iterator snditer = mActiveSounds.begin();
while(snditer != mActiveSounds.end())
{
if(snditer->second.first == ptr && snditer->second.second == soundId)
{
snditer->first->setFadeout(duration);
}
snditer++;
}
}
bool SoundManager::getSoundPlaying(const MWWorld::Ptr &ptr, const std::string& soundId) const
{
return isPlaying(ptr, soundId);
@ -520,6 +534,7 @@ namespace MWSound
timePassed += duration;
if(timePassed < (1.0f/30.0f))
return;
duration = timePassed;
timePassed = 0.0f;
// Make sure music is still playing
@ -542,6 +557,7 @@ namespace MWSound
);
// Check if any sounds are finished playing, and trash them
// Lower volume on fading out sounds
SoundMap::iterator snditer = mActiveSounds.begin();
while(snditer != mActiveSounds.end())
{
@ -556,6 +572,16 @@ namespace MWSound
const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]);
snditer->first->setPosition(objpos);
}
//update fade out
if(snditer->first->mFadeOutTime>0)
{
float soundDuration=duration;
if(soundDuration>snditer->first->mFadeOutTime)
soundDuration=snditer->first->mFadeOutTime;
snditer->first->setVolume(snditer->first->mVolume
- soundDuration / snditer->first->mFadeOutTime * snditer->first->mVolume);
snditer->first->mFadeOutTime -= soundDuration;
}
snditer->first->update();
snditer++;
}

@ -106,13 +106,15 @@ namespace MWSound
virtual MWBase::SoundPtr playTrack(const DecoderPtr& decoder, PlayType type);
///< Play a 2D audio track, using a custom decoder
virtual MWBase::SoundPtr playSound(const std::string& soundId, float volume, float pitch, PlayType type=Play_TypeSfx, PlayMode mode=Play_Normal);
virtual MWBase::SoundPtr 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
///< @param offset value from [0,1], when to start playback. 0 is beginning, 1 is end.
virtual MWBase::SoundPtr playSound3D(const MWWorld::Ptr &reference, const std::string& soundId,
float volume, float pitch, PlayType type=Play_TypeSfx,
PlayMode mode=Play_Normal);
PlayMode mode=Play_Normal, float offset=0);
///< Play a sound from an object
///< @param offset value from [0,1], when to start playback. 0 is beginning, 1 is end.
virtual void stopSound3D(const MWWorld::Ptr &reference, const std::string& soundId);
///< Stop the given object from playing the given sound,
@ -126,6 +128,12 @@ namespace MWSound
virtual void stopSound(const std::string& soundId);
///< Stop a non-3d looping sound
virtual void fadeOutSound3D(const MWWorld::Ptr &reference, const std::string& soundId, float duration);
///< Fade out given sound (that is already playing) of given object
///< @param reference Reference to object, whose sound is faded out
///< @param soundId ID of the sound to fade out.
///< @param duration Time until volume reaches 0.
virtual bool getSoundPlaying(const MWWorld::Ptr &reference, const std::string& soundId) const;
///< Is the given sound currently playing on the given object?

@ -11,7 +11,7 @@ const MWWorld::Ptr& MWWorld::Action::getTarget() const
return mTarget;
}
MWWorld::Action::Action (bool keepSound, const Ptr& target) : mKeepSound (keepSound), mTarget (target)
MWWorld::Action::Action (bool keepSound, const Ptr& target) : mKeepSound (keepSound), mTarget (target), mSoundOffset(0)
{}
MWWorld::Action::~Action() {}
@ -21,14 +21,16 @@ void MWWorld::Action::execute (const Ptr& actor)
if (!mSoundId.empty())
{
if (mKeepSound && actor.getRefData().getHandle()=="player")
MWBase::Environment::get().getSoundManager()->playSound(mSoundId, 1.0, 1.0);
MWBase::Environment::get().getSoundManager()->playSound(mSoundId, 1.0, 1.0,
MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Normal,mSoundOffset);
else
{
bool local = mTarget.isEmpty() || !mTarget.isInCell(); // no usable target
MWBase::Environment::get().getSoundManager()->playSound3D(local ? actor : mTarget,
mSoundId, 1.0, 1.0, MWBase::SoundManager::Play_TypeSfx,
mKeepSound ? MWBase::SoundManager::Play_NoTrack : MWBase::SoundManager::Play_Normal);
mKeepSound ? MWBase::SoundManager::Play_NoTrack : MWBase::SoundManager::Play_Normal,
mSoundOffset);
}
}
@ -39,3 +41,8 @@ void MWWorld::Action::setSound (const std::string& id)
{
mSoundId = id;
}
void MWWorld::Action::setSoundOffset(float offset)
{
mSoundOffset=offset;
}

@ -12,6 +12,7 @@ namespace MWWorld
{
std::string mSoundId;
bool mKeepSound;
float mSoundOffset;
Ptr mTarget;
// not implemented
@ -34,6 +35,7 @@ namespace MWWorld
void execute (const Ptr& actor);
void setSound (const std::string& id);
void setSoundOffset(float offset);
};
}

Loading…
Cancel
Save