From 846e7b6578058cf6d52bf2bf0b2133f84220d670 Mon Sep 17 00:00:00 2001 From: erihel Date: Mon, 8 Apr 2013 01:42:12 +0200 Subject: * Adjusted pan computing function from original game (2D sound should work correctly) * Set max sound distance to 110.0f to match original colobot (for issue #123) --- src/sound/oalsound/alsound.cpp | 70 ++++++++++++++++++++++++++++++++++-------- src/sound/oalsound/alsound.h | 3 ++ src/sound/oalsound/channel.cpp | 49 ++++++++++++++++++----------- 3 files changed, 91 insertions(+), 31 deletions(-) diff --git a/src/sound/oalsound/alsound.cpp b/src/sound/oalsound/alsound.cpp index 21f11b7..a5a6989 100644 --- a/src/sound/oalsound/alsound.cpp +++ b/src/sound/oalsound/alsound.cpp @@ -28,6 +28,8 @@ ALSound::ALSound() mMusicVolume = 1.0f; mMute = false; mCurrentMusic = nullptr; + mEye.LoadZero(); + mLookat.LoadZero(); } @@ -82,7 +84,7 @@ bool ALSound::Create(bool b3D) } alcMakeContextCurrent(mContext); alListenerf(AL_GAIN, mAudioVolume); - alDistanceModel(AL_LINEAR_DISTANCE); + alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED); mCurrentMusic = new Channel(); GetLogger()->Info("Done.\n"); @@ -94,18 +96,6 @@ bool ALSound::Create(bool b3D) void ALSound::SetSound3D(bool bMode) { m3D = bMode; - - if (!m3D) { - float orientation[] = {0.0f, 0.0f, 0.0f, 0.f, 1.f, 0.f}; - alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f); - alListenerfv(AL_ORIENTATION, orientation); - - for (auto c : mChannels) { - if (c.second->IsPlaying()) { - c.second->SetPosition(Math::Vector(0.0f, 0.0f, 0.0f)); - } - } - } } @@ -326,6 +316,9 @@ int ALSound::Play(Sound sound, Math::Vector pos, float amplitude, float frequenc } } Position(channel, pos); + if (!m3D) { + ComputeVolumePan2D(channel, pos); + } // setting initial values mChannels[channel]->SetStartAmplitude(amplitude); @@ -384,6 +377,8 @@ bool ALSound::Position(int channel, Math::Vector pos) if (m3D) { mChannels[channel]->SetPosition(pos); + } else { + ComputeVolumePan2D(channel, pos); } return true; } @@ -447,6 +442,7 @@ bool ALSound::MuteAll(bool bMute) return true; } + void ALSound::FrameMove(float delta) { if (!mEnabled) @@ -507,6 +503,8 @@ void ALSound::FrameMove(float delta) void ALSound::SetListener(Math::Vector eye, Math::Vector lookat) { + mEye = eye; + mLookat = lookat; if (m3D) { float orientation[] = {lookat.x, lookat.y, lookat.z, 0.f, 1.f, 0.f}; alListener3f(AL_POSITION, eye.x, eye.y, eye.z); @@ -600,3 +598,49 @@ void ALSound::SuspendMusic() mCurrentMusic->Stop(); } + + +void ALSound::ComputeVolumePan2D(int channel, Math::Vector &pos) +{ + float dist, a, g; + + if (VectorsEqual(pos, mEye)) { + mChannels[channel]->SetVolume(1.0f); // maximum volume + mChannels[channel]->SetPosition(Math::Vector()); // at the center + return; + } + + dist = Distance(pos, mEye); + if ( dist >= 110.0f ) { // very far? + mChannels[channel]->SetVolume(0.0f); // silence + mChannels[channel]->SetPosition(Math::Vector()); // at the center + return; + } else if ( dist <= 10.0f ) { // very close? + mChannels[channel]->SetVolume(1.0f); // maximum volume + mChannels[channel]->SetPosition(Math::Vector()); // at the center + return; + } + mChannels[channel]->SetVolume(1.0f - ((dist - 10.0f) / 100.0f)); + + a = fmodf(Angle(mLookat, mEye), Math::PI * 2.0f); + g = fmodf(Angle(pos, mEye), Math::PI * 2.0f); + + if ( a < 0.0f ) { + a += Math::PI * 2.0f; + } + if ( g < 0.0f ) { + g += Math::PI * 2.0f; + } + + if ( a < g ) { + if (a + Math::PI * 2.0f - g < g - a ) { + a += Math::PI * 2.0f; + } + } else { + if ( g + Math::PI * 2.0f - a < a - g ) { + g += Math::PI * 2.0f; + } + } + + mChannels[channel]->SetPosition( Math::Vector(sinf(g - a), 0.0f, 0.0f) ); +} diff --git a/src/sound/oalsound/alsound.h b/src/sound/oalsound/alsound.h index bdf06b1..725aa2a 100644 --- a/src/sound/oalsound/alsound.h +++ b/src/sound/oalsound/alsound.h @@ -81,6 +81,7 @@ class ALSound : public CSoundInterface void CleanUp(); int GetPriority(Sound); bool SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded); + void ComputeVolumePan2D(int channel, Math::Vector &pos); bool mEnabled; bool m3D; @@ -93,4 +94,6 @@ class ALSound : public CSoundInterface std::map mChannels; std::deque mMusicCache; Channel *mCurrentMusic; + Math::Vector mEye; + Math::Vector mLookat; }; diff --git a/src/sound/oalsound/channel.cpp b/src/sound/oalsound/channel.cpp index f5967ab..746282e 100644 --- a/src/sound/oalsound/channel.cpp +++ b/src/sound/oalsound/channel.cpp @@ -49,20 +49,25 @@ Channel::~Channel() { bool Channel::Play() { - if (!mReady || mBuffer == nullptr) + if (!mReady || mBuffer == nullptr) { return false; + } alSourcei(mSource, AL_LOOPING, static_cast(mLoop)); + alSourcei(mSource, AL_REFERENCE_DISTANCE, 10.0f); + alSourcei(mSource, AL_MAX_DISTANCE, 110.0f); alSourcePlay(mSource); - if (alCheck()) + if (alCheck()) { GetLogger()->Warn("Could not play audio sound source. Code: %d\n", alGetCode()); + } return true; } bool Channel::SetPosition(Math::Vector pos) { - if (!mReady || mBuffer == nullptr) + if (!mReady || mBuffer == nullptr) { return false; + } alSource3f(mSource, AL_POSITION, pos.x, pos.y, pos.z); if (alCheck()) { @@ -75,8 +80,9 @@ bool Channel::SetPosition(Math::Vector pos) { bool Channel::SetFrequency(float freq) { - if (!mReady || mBuffer == nullptr) + if (!mReady || mBuffer == nullptr) { return false; + } alSourcef(mSource, AL_PITCH, freq); if (alCheck()) { @@ -90,8 +96,9 @@ bool Channel::SetFrequency(float freq) float Channel::GetFrequency() { ALfloat freq; - if (!mReady || mBuffer == nullptr) + if (!mReady || mBuffer == nullptr) { return 0; + } alGetSourcef(mSource, AL_PITCH, &freq); if (alCheck()) { @@ -105,8 +112,9 @@ float Channel::GetFrequency() bool Channel::SetVolume(float vol) { - if (!mReady || vol < 0 || mBuffer == nullptr) + if (!mReady || vol < 0 || mBuffer == nullptr) { return false; + } alSourcef(mSource, AL_GAIN, vol); if (alCheck()) { @@ -120,8 +128,9 @@ bool Channel::SetVolume(float vol) float Channel::GetVolume() { ALfloat vol; - if (!mReady || mBuffer == nullptr) + if (!mReady || mBuffer == nullptr) { return 0; + } alGetSourcef(mSource, AL_GAIN, &vol); if (alCheck()) { @@ -201,8 +210,9 @@ void Channel::ResetOper() Sound Channel::GetSoundType() { - if (!mReady || mBuffer == nullptr) + if (!mReady || mBuffer == nullptr) { return SOUND_NONE; + } return mBuffer->GetSoundType(); } @@ -230,10 +240,7 @@ bool Channel::SetBuffer(Buffer *buffer) { bool Channel::FreeBuffer() { - if (!mReady) - return false; - - if (!mBuffer) { + if (!mReady || !mBuffer) { return false; } @@ -247,8 +254,9 @@ bool Channel::FreeBuffer() { bool Channel::IsPlaying() { ALint status; - if (!mReady || mBuffer == nullptr) + if (!mReady || mBuffer == nullptr) { return false; + } alGetSourcei(mSource, AL_SOURCE_STATE, &status); if (alCheck()) { @@ -270,8 +278,9 @@ bool Channel::IsLoaded() { bool Channel::Stop() { - if (!mReady || mBuffer == nullptr) + if (!mReady || mBuffer == nullptr) { return false; + } alSourceStop(mSource); if (alCheck()) { @@ -284,8 +293,9 @@ bool Channel::Stop() { float Channel::GetCurrentTime() { - if (!mReady || mBuffer == nullptr) + if (!mReady || mBuffer == nullptr) { return 0.0f; + } ALfloat current; alGetSourcef(mSource, AL_SEC_OFFSET, ¤t); @@ -299,19 +309,22 @@ float Channel::GetCurrentTime() void Channel::SetCurrentTime(float current) { - if (!mReady || mBuffer == nullptr) + if (!mReady || mBuffer == nullptr) { return; + } alSourcef(mSource, AL_SEC_OFFSET, current); - if (alCheck()) + if (alCheck()) { GetLogger()->Warn("Could not get source current play time. Code: %d\n", alGetCode()); + } } float Channel::GetDuration() { - if (!mReady || mBuffer == nullptr) + if (!mReady || mBuffer == nullptr) { return 0.0f; + } return mBuffer->GetDuration(); } -- cgit v1.2.3-1-g7c22