diff --git a/src/sound/oalsound/alsound.cpp b/src/sound/oalsound/alsound.cpp index 02e24038..3ce975be 100644 --- a/src/sound/oalsound/alsound.cpp +++ b/src/sound/oalsound/alsound.cpp @@ -314,12 +314,12 @@ int ALSound::Play(Sound sound, Math::Vector pos, float amplitude, float frequenc return -1; } } - + Position(channel, pos); if (!m3D) { ComputeVolumePan2D(channel, pos); } else { - mChannels[channel]->SetVolume(1.0f); + mChannels[channel]->SetVolumeAtrib(1.0f); } // setting initial values @@ -328,7 +328,7 @@ int ALSound::Play(Sound sound, Math::Vector pos, float amplitude, float frequenc mChannels[channel]->SetChangeFrequency(1.0f); mChannels[channel]->ResetOper(); mChannels[channel]->SetFrequency(frequency); - mChannels[channel]->SetVolume(powf(amplitude * mChannels[channel]->GetVolume(), 0.2f) * mAudioVolume); + mChannels[channel]->SetVolume(powf(amplitude * mChannels[channel]->GetVolumeAtrib(), 0.2f) * mAudioVolume); mChannels[channel]->SetLoop(bLoop); mChannels[channel]->Play(); @@ -378,9 +378,14 @@ bool ALSound::Position(int channel, Math::Vector pos) } if (m3D) { - mChannels[channel]->SetPosition(pos); + mChannels[channel]->SetPan(pos); } else { ComputeVolumePan2D(channel, pos); + + if (!mChannels[channel]->HasEnvelope()) { + float volume = mChannels[channel]->GetStartAmplitude(); + mChannels[channel]->SetVolume(powf(volume * mChannels[channel]->GetVolumeAtrib(), 0.2f) * mAudioVolume); + } } return true; } @@ -477,8 +482,8 @@ void ALSound::FrameMove(float delta) // setting volume volume = progress * (oper.finalAmplitude - it.second->GetStartAmplitude()); - volume = (volume + it.second->GetStartAmplitude()); - it.second->SetVolume(powf(volume * it.second->GetVolume(), 0.2f) * mAudioVolume); + volume = volume + it.second->GetStartAmplitude(); + it.second->SetVolume(powf(volume * it.second->GetVolumeAtrib(), 0.2f) * mAudioVolume); // setting frequency frequency = progress; @@ -515,9 +520,22 @@ void ALSound::SetListener(Math::Vector eye, Math::Vector lookat) alListener3f(AL_POSITION, eye.x, eye.y, eye.z); alListenerfv(AL_ORIENTATION, orientation); } else { - float orientation[] = {0.0f, 0.0f, -1.0f, 0.f, 1.f, 0.f}; + 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); + + // recalculate sound position + for (auto it : mChannels) { + if (it.second->IsPlaying()) { + Math::Vector pos = it.second->GetPosition(); + ComputeVolumePan2D(it.first, pos); + + if (!it.second->HasEnvelope()) { + float volume = it.second->GetStartAmplitude(); + it.second->SetVolume(powf(volume * it.second->GetVolumeAtrib(), 0.2f) * mAudioVolume); + } + } + } } } @@ -612,24 +630,25 @@ void ALSound::SuspendMusic() void ALSound::ComputeVolumePan2D(int channel, Math::Vector &pos) { float dist, a, g; + mChannels[channel]->SetPosition(pos); if (VectorsEqual(pos, mEye)) { - mChannels[channel]->SetVolume(1.0f); // maximum volume - mChannels[channel]->SetPosition(Math::Vector()); // at the center + mChannels[channel]->SetVolumeAtrib(1.0f); // maximum volume + mChannels[channel]->SetPan(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 + mChannels[channel]->SetVolumeAtrib(0.0f); // silence + mChannels[channel]->SetPan(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 + mChannels[channel]->SetVolumeAtrib(1.0f); // maximum volume + mChannels[channel]->SetPan(Math::Vector()); // at the center return; } - mChannels[channel]->SetVolume(1.0f - ((dist - 10.0f) / 100.0f)); + mChannels[channel]->SetVolumeAtrib(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); @@ -651,5 +670,5 @@ void ALSound::ComputeVolumePan2D(int channel, Math::Vector &pos) } } - mChannels[channel]->SetPosition( Math::Vector(sinf(g - a), 0.0f, 0.0f) ); + mChannels[channel]->SetPan( Math::Vector(sinf(g - a), 0.0f, 0.0f) ); } diff --git a/src/sound/oalsound/channel.cpp b/src/sound/oalsound/channel.cpp index 01ec3de6..c5b05fae 100644 --- a/src/sound/oalsound/channel.cpp +++ b/src/sound/oalsound/channel.cpp @@ -17,7 +17,8 @@ #include "channel.h" -Channel::Channel() { +Channel::Channel() +{ alGenSources(1, &mSource); if (alCheck()) { @@ -35,10 +36,12 @@ Channel::Channel() { mStartAmplitude = 0.0f; mStartFrequency = 0.0f; mChangeFrequency = 0.0f; + mVolume = 0.0f; } -Channel::~Channel() { +Channel::~Channel() +{ if (mReady) { alSourceStop(mSource); alSourcei(mSource, AL_BUFFER, 0); @@ -49,7 +52,8 @@ Channel::~Channel() { } -bool Channel::Play() { +bool Channel::Play() +{ if (!mReady || mBuffer == nullptr) { return false; } @@ -65,7 +69,8 @@ bool Channel::Play() { } -bool Channel::SetPosition(Math::Vector pos) { +bool Channel::SetPan(Math::Vector pos) +{ if (!mReady || mBuffer == nullptr) { return false; } @@ -79,6 +84,18 @@ bool Channel::SetPosition(Math::Vector pos) { } +void Channel::SetPosition(Math::Vector pos) +{ + mPosition = pos; +} + + +Math::Vector Channel::GetPosition() +{ + return mPosition; +} + + bool Channel::SetFrequency(float freq) { if (!mReady || mBuffer == nullptr) { @@ -143,6 +160,19 @@ float Channel::GetVolume() } +void Channel::SetVolumeAtrib(float volume) +{ + mVolume = volume; +} + + +float Channel::GetVolumeAtrib() +{ + return mVolume; +} + + + int Channel::GetPriority() { return mPriority; diff --git a/src/sound/oalsound/channel.h b/src/sound/oalsound/channel.h index f5f3bb9b..6717f031 100644 --- a/src/sound/oalsound/channel.h +++ b/src/sound/oalsound/channel.h @@ -48,7 +48,10 @@ class Channel bool Play(); bool Stop(); - bool SetPosition(Math::Vector); + + bool SetPan(Math::Vector); + void SetPosition(Math::Vector); + Math::Vector GetPosition(); bool SetFrequency(float); float GetFrequency(); @@ -59,6 +62,9 @@ class Channel bool SetVolume(float); float GetVolume(); + void SetVolumeAtrib(float); + float GetVolumeAtrib(); + bool IsPlaying(); bool IsReady(); bool IsLoaded(); @@ -98,8 +104,10 @@ class Channel float mStartFrequency; float mChangeFrequency; float mInitFrequency; + float mVolume; std::deque mOper; bool mReady; bool mLoop; bool mMute; + Math::Vector mPosition; };