mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-09-09 12:25:17 -04:00
doppler take 2
This commit is contained in:
parent
abbbeefdbd
commit
c541cb96cc
@ -293,6 +293,7 @@ bool Launcher::SettingsPage::loadSettings()
|
||||
}
|
||||
}
|
||||
loadSettingBool(Settings::sound().mCameraListener, *cameraListenerCheckBox);
|
||||
dopplerSpinBox->setValue(Settings::sound().mDopplerFactor);
|
||||
}
|
||||
|
||||
// Interface Changes
|
||||
@ -486,6 +487,8 @@ void Launcher::SettingsPage::saveSettings()
|
||||
|
||||
const bool cCameraListener = cameraListenerCheckBox->checkState() != Qt::Unchecked;
|
||||
Settings::sound().mCameraListener.set(cCameraListener);
|
||||
|
||||
Settings::sound().mDopplerFactor.set(dopplerSpinBox->value());
|
||||
}
|
||||
|
||||
// Interface Changes
|
||||
|
@ -1235,6 +1235,50 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="dopplerLabel">
|
||||
<property name="toolTip">
|
||||
<string>Controls the strength of the doppler effect. Zero means it is completely disabled.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Doppler Factor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="dopplerSpinBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>283</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.250000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
|
@ -234,6 +234,8 @@ namespace MWBase
|
||||
const osg::Vec3f& pos, const osg::Vec3f& dir, const osg::Vec3f& up, bool underwater)
|
||||
= 0;
|
||||
|
||||
virtual void setListenerVel(const osg::Vec3f& vel) = 0;
|
||||
|
||||
virtual void updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) = 0;
|
||||
|
||||
void setSimulationTimeScale(float scale) { mSimulationTimeScale = scale; }
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <components/misc/constants.hpp>
|
||||
#include <components/misc/resourcehelpers.hpp>
|
||||
#include <components/misc/thread.hpp>
|
||||
#include <components/settings/values.hpp>
|
||||
#include <components/vfs/manager.hpp>
|
||||
|
||||
#include "efxpresets.h"
|
||||
@ -1137,12 +1138,13 @@ namespace MWSound
|
||||
|
||||
alSourcef(source, AL_GAIN, gain);
|
||||
alSourcef(source, AL_PITCH, pitch);
|
||||
alSourcef(source, AL_DOPPLER_FACTOR, 0.0f);
|
||||
alSourcefv(source, AL_POSITION, pos.ptr());
|
||||
alSource3f(source, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
||||
alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void OpenALOutput::initCommon3D(ALuint source, const osg::Vec3f& pos, ALfloat mindist, ALfloat maxdist,
|
||||
void OpenALOutput::initCommon3D(ALuint source, const osg::Vec3f& pos, const osg::Vec3f& vel, ALfloat mindist, ALfloat maxdist,
|
||||
ALfloat gain, ALfloat pitch, bool loop, bool useenv)
|
||||
{
|
||||
alSourcef(source, AL_REFERENCE_DISTANCE, mindist);
|
||||
@ -1177,13 +1179,14 @@ namespace MWSound
|
||||
|
||||
alSourcef(source, AL_GAIN, gain);
|
||||
alSourcef(source, AL_PITCH, pitch);
|
||||
alSourcef(source, AL_DOPPLER_FACTOR, Settings::sound().mDopplerFactor);
|
||||
alSourcefv(source, AL_POSITION, pos.ptr());
|
||||
alSource3f(source, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
||||
alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
||||
alSourcefv(source, AL_VELOCITY, vel.ptr());
|
||||
}
|
||||
|
||||
void OpenALOutput::updateCommon(
|
||||
ALuint source, const osg::Vec3f& pos, ALfloat maxdist, ALfloat gain, ALfloat pitch, bool useenv)
|
||||
ALuint source, const osg::Vec3f& pos, const osg::Vec3f& vel, ALfloat maxdist, ALfloat gain, ALfloat pitch, bool useenv)
|
||||
{
|
||||
if (useenv && mListenerEnv == Env_Underwater && !mWaterFilter)
|
||||
{
|
||||
@ -1195,7 +1198,7 @@ namespace MWSound
|
||||
alSourcef(source, AL_PITCH, pitch);
|
||||
alSourcefv(source, AL_POSITION, pos.ptr());
|
||||
alSource3f(source, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
||||
alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
||||
alSourcefv(source, AL_VELOCITY, vel.ptr());
|
||||
}
|
||||
|
||||
bool OpenALOutput::playSound(Sound* sound, Sound_Handle data, float offset)
|
||||
@ -1248,7 +1251,7 @@ namespace MWSound
|
||||
}
|
||||
source = mFreeSources.front();
|
||||
|
||||
initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(),
|
||||
initCommon3D(source, sound->getPosition(), sound->getVelocity(), sound->getMinDistance(), sound->getMaxDistance(),
|
||||
sound->getRealVolume(), getTimeScaledPitch(sound), sound->getIsLooping(), sound->getUseEnv());
|
||||
alSourcei(source, AL_BUFFER, GET_PTRID(data));
|
||||
alSourcef(source, AL_SEC_OFFSET, offset);
|
||||
@ -1312,7 +1315,7 @@ namespace MWSound
|
||||
return;
|
||||
ALuint source = GET_PTRID(sound->mHandle);
|
||||
|
||||
updateCommon(source, sound->getPosition(), sound->getMaxDistance(), sound->getRealVolume(),
|
||||
updateCommon(source, sound->getPosition(), sound->getVelocity(), sound->getMaxDistance(), sound->getRealVolume(),
|
||||
getTimeScaledPitch(sound), sound->getUseEnv());
|
||||
getALError();
|
||||
}
|
||||
@ -1360,7 +1363,7 @@ namespace MWSound
|
||||
if (sound->getIsLooping())
|
||||
Log(Debug::Warning) << "Warning: cannot loop stream \"" << decoder->getName() << "\"";
|
||||
|
||||
initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(),
|
||||
initCommon3D(source, sound->getPosition(), sound->getVelocity(), sound->getMinDistance(), sound->getMaxDistance(),
|
||||
sound->getRealVolume(), getTimeScaledPitch(sound), false, sound->getUseEnv());
|
||||
if (getALError() != AL_NO_ERROR)
|
||||
return false;
|
||||
@ -1443,7 +1446,7 @@ namespace MWSound
|
||||
OpenAL_SoundStream* stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle);
|
||||
ALuint source = stream->mSource;
|
||||
|
||||
updateCommon(source, sound->getPosition(), sound->getMaxDistance(), sound->getRealVolume(),
|
||||
updateCommon(source, sound->getPosition(), sound->getVelocity(), sound->getMaxDistance(), sound->getRealVolume(),
|
||||
getTimeScaledPitch(sound), sound->getUseEnv());
|
||||
getALError();
|
||||
}
|
||||
@ -1459,12 +1462,13 @@ namespace MWSound
|
||||
}
|
||||
|
||||
void OpenALOutput::updateListener(
|
||||
const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, Environment env)
|
||||
const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, const osg::Vec3f& vel, Environment env)
|
||||
{
|
||||
if (mContext)
|
||||
{
|
||||
ALfloat orient[6] = { atdir.x(), atdir.y(), atdir.z(), updir.x(), updir.y(), updir.z() };
|
||||
alListenerfv(AL_POSITION, pos.ptr());
|
||||
alListenerfv(AL_VELOCITY, vel.ptr());
|
||||
alListenerfv(AL_ORIENTATION, orient);
|
||||
|
||||
if (env != mListenerEnv)
|
||||
@ -1497,6 +1501,7 @@ namespace MWSound
|
||||
}
|
||||
|
||||
mListenerPos = pos;
|
||||
mListenerVel = vel;
|
||||
mListenerEnv = env;
|
||||
}
|
||||
|
||||
@ -1583,6 +1588,7 @@ namespace MWSound
|
||||
, mDevice(nullptr)
|
||||
, mContext(nullptr)
|
||||
, mListenerPos(0.0f, 0.0f, 0.0f)
|
||||
, mListenerVel(0.0f, 0.0f, 0.0f)
|
||||
, mListenerEnv(Env_Normal)
|
||||
, mWaterFilter(0)
|
||||
, mWaterEffect(0)
|
||||
|
@ -46,6 +46,7 @@ namespace MWSound
|
||||
StreamVec mActiveStreams;
|
||||
|
||||
osg::Vec3f mListenerPos;
|
||||
osg::Vec3f mListenerVel;
|
||||
Environment mListenerEnv;
|
||||
|
||||
ALuint mWaterFilter;
|
||||
@ -64,11 +65,11 @@ namespace MWSound
|
||||
std::unique_ptr<DefaultDeviceThread> mDefaultDeviceThread;
|
||||
|
||||
void initCommon2D(ALuint source, const osg::Vec3f& pos, ALfloat gain, ALfloat pitch, bool loop, bool useenv);
|
||||
void initCommon3D(ALuint source, const osg::Vec3f& pos, ALfloat mindist, ALfloat maxdist, ALfloat gain,
|
||||
void initCommon3D(ALuint source, const osg::Vec3f& pos, const osg::Vec3f& vel, ALfloat mindist, ALfloat maxdist, ALfloat gain,
|
||||
ALfloat pitch, bool loop, bool useenv);
|
||||
|
||||
void updateCommon(
|
||||
ALuint source, const osg::Vec3f& pos, ALfloat maxdist, ALfloat gain, ALfloat pitch, bool useenv);
|
||||
ALuint source, const osg::Vec3f& pos, const osg::Vec3f& vel, ALfloat maxdist, ALfloat gain, ALfloat pitch, bool useenv);
|
||||
|
||||
float getTimeScaledPitch(SoundBase* sound);
|
||||
|
||||
@ -109,7 +110,7 @@ namespace MWSound
|
||||
void finishUpdate() override;
|
||||
|
||||
void updateListener(
|
||||
const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, Environment env) override;
|
||||
const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, const osg::Vec3f& vel, Environment env) override;
|
||||
|
||||
void pauseSounds(int types) override;
|
||||
void resumeSounds(int types) override;
|
||||
|
@ -31,6 +31,8 @@ namespace MWSound
|
||||
struct SoundParams
|
||||
{
|
||||
osg::Vec3f mPos;
|
||||
osg::Vec3f mLastPos;
|
||||
osg::Vec3f mVel;
|
||||
float mVolume = 1.0f;
|
||||
float mBaseVolume = 1.0f;
|
||||
float mPitch = 1.0f;
|
||||
@ -57,6 +59,8 @@ namespace MWSound
|
||||
|
||||
public:
|
||||
void setPosition(const osg::Vec3f& pos) { mParams.mPos = pos; }
|
||||
void setLastPosition(const osg::Vec3f& lastpos) { mParams.mLastPos = lastpos; }
|
||||
void setVelocity(const osg::Vec3f& vel) { mParams.mVel = vel; }
|
||||
void setVolume(float volume) { mParams.mVolume = volume; }
|
||||
void setBaseVolume(float volume) { mParams.mBaseVolume = volume; }
|
||||
void setFadeout(float duration) { setFade(duration, 0.0, Play_StopAtFadeEnd); }
|
||||
@ -150,6 +154,8 @@ namespace MWSound
|
||||
}
|
||||
|
||||
const osg::Vec3f& getPosition() const { return mParams.mPos; }
|
||||
const osg::Vec3f& getLastPosition() const { return mParams.mLastPos; }
|
||||
const osg::Vec3f& getVelocity() const {return mParams.mVel; }
|
||||
float getRealVolume() const { return mParams.mVolume * mParams.mBaseVolume * mParams.mFadeVolume; }
|
||||
float getPitch() const { return mParams.mPitch; }
|
||||
float getMinDistance() const { return mParams.mMinDistance; }
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <components/debug/debuglog.hpp>
|
||||
#include <components/misc/resourcehelpers.hpp>
|
||||
#include <components/misc/rng.hpp>
|
||||
#include <components/misc/strings/conversion.hpp>
|
||||
#include <components/settings/values.hpp>
|
||||
#include <components/vfs/manager.hpp>
|
||||
#include <components/vfs/pathutil.hpp>
|
||||
@ -119,6 +120,7 @@ namespace MWSound
|
||||
, mListenerPos(0, 0, 0)
|
||||
, mListenerDir(1, 0, 0)
|
||||
, mListenerUp(0, 0, 1)
|
||||
, mListenerVel(0, 0, 0)
|
||||
, mUnderwaterSound(nullptr)
|
||||
, mNearWaterSound(nullptr)
|
||||
, mPlaybackPaused(false)
|
||||
@ -959,8 +961,16 @@ namespace MWSound
|
||||
mUnderwaterSound = nullptr;
|
||||
}
|
||||
|
||||
float physicsFramerate = 60.f;
|
||||
if (const char* env = getenv("OPENMW_PHYSICS_FPS"))
|
||||
{
|
||||
if (const auto physFramerate = Misc::StringUtils::toNumeric<float>(env);
|
||||
physFramerate.has_value() && *physFramerate > 0)
|
||||
physicsFramerate = *physFramerate;
|
||||
}
|
||||
|
||||
mOutput->startUpdate();
|
||||
mOutput->updateListener(mListenerPos, mListenerDir, mListenerUp, env);
|
||||
mOutput->updateListener(mListenerPos, mListenerDir, mListenerUp, mListenerVel, env);
|
||||
|
||||
updateMusic(duration);
|
||||
|
||||
@ -977,7 +987,11 @@ namespace MWSound
|
||||
if (sound->getIs3D())
|
||||
{
|
||||
if (!ptr.isEmpty())
|
||||
{
|
||||
sound->setLastPosition(sound->getPosition());
|
||||
sound->setPosition(ptr.getRefData().getPosition().asVec3());
|
||||
sound->setVelocity((sound->getPosition() - sound->getLastPosition()) * physicsFramerate);
|
||||
}
|
||||
|
||||
cull3DSound(sound);
|
||||
}
|
||||
@ -1013,8 +1027,10 @@ namespace MWSound
|
||||
{
|
||||
if (!ptr.isEmpty())
|
||||
{
|
||||
sound->setLastPosition(sound->getPosition());
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
sound->setPosition(world->getActorHeadTransform(ptr).getTrans());
|
||||
sound->setVelocity((sound->getPosition() - sound->getLastPosition()) * physicsFramerate);
|
||||
}
|
||||
|
||||
cull3DSound(sound);
|
||||
@ -1153,6 +1169,11 @@ namespace MWSound
|
||||
mWaterSoundUpdater.setUnderwater(underwater);
|
||||
}
|
||||
|
||||
void SoundManager::setListenerVel(const osg::Vec3f& vel)
|
||||
{
|
||||
mListenerVel = vel;
|
||||
}
|
||||
|
||||
void SoundManager::updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated)
|
||||
{
|
||||
SoundMap::iterator snditer = mActiveSounds.find(old.mRef);
|
||||
|
@ -92,6 +92,7 @@ namespace MWSound
|
||||
osg::Vec3f mListenerPos;
|
||||
osg::Vec3f mListenerDir;
|
||||
osg::Vec3f mListenerUp;
|
||||
osg::Vec3f mListenerVel;
|
||||
|
||||
int mPausedSoundTypes[BlockerType::MaxCount] = {};
|
||||
|
||||
@ -283,6 +284,8 @@ namespace MWSound
|
||||
void setListenerPosDir(
|
||||
const osg::Vec3f& pos, const osg::Vec3f& dir, const osg::Vec3f& up, bool underwater) override;
|
||||
|
||||
void setListenerVel(const osg::Vec3f& vel) override;
|
||||
|
||||
void updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) override;
|
||||
|
||||
void clear() override;
|
||||
|
@ -62,7 +62,7 @@ namespace MWSound
|
||||
virtual void finishUpdate() = 0;
|
||||
|
||||
virtual void updateListener(
|
||||
const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, Environment env)
|
||||
const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, const osg::Vec3f& vel, Environment env)
|
||||
= 0;
|
||||
|
||||
virtual void pauseSounds(int types) = 0;
|
||||
|
@ -461,6 +461,11 @@ namespace MWWorld
|
||||
|
||||
update(magicBoltState, duration);
|
||||
|
||||
for (const auto& sound : magicBoltState.mSounds)
|
||||
{
|
||||
sound->setVelocity(direction * speed);
|
||||
}
|
||||
|
||||
// For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit
|
||||
// result.
|
||||
std::vector<MWWorld::Ptr> targetActors;
|
||||
|
@ -1467,6 +1467,8 @@ namespace MWWorld
|
||||
void World::queueMovement(const Ptr& ptr, const osg::Vec3f& velocity)
|
||||
{
|
||||
mPhysics->queueObjectMovement(ptr, velocity);
|
||||
if(ptr == MWMechanics::getPlayer())
|
||||
MWBase::Environment::get().getSoundManager()->setListenerVel(velocity);
|
||||
}
|
||||
|
||||
void World::updateAnimatedCollisionShape(const Ptr& ptr)
|
||||
|
@ -24,6 +24,7 @@ namespace Settings
|
||||
SettingValue<HrtfMode> mHrtfEnable{ mIndex, "Sound", "hrtf enable" };
|
||||
SettingValue<std::string> mHrtf{ mIndex, "Sound", "hrtf" };
|
||||
SettingValue<bool> mCameraListener{ mIndex, "Sound", "camera listener" };
|
||||
SettingValue<float> mDopplerFactor{ mIndex, "Sound", "doppler factor", makeClampSanitizerFloat(0, 1) };
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -627,6 +627,9 @@ hrtf =
|
||||
# Specifies whether to use camera as audio listener
|
||||
camera listener = false
|
||||
|
||||
# Specifies strength of doppler effect
|
||||
doppler factor = 0.25
|
||||
|
||||
[Video]
|
||||
|
||||
# Resolution of the OpenMW window or screen.
|
||||
|
Loading…
x
Reference in New Issue
Block a user