forked from mirror/openmw-tes3mp
Old door sound fades out on door open/close. Door sound is synchronised to angle on action.
This commit is contained in:
parent
0923306404
commit
f297c21e4d
10 changed files with 118 additions and 22 deletions
|
@ -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…
Reference in a new issue