summaryrefslogtreecommitdiffstats
path: root/src/sound
diff options
context:
space:
mode:
Diffstat (limited to 'src/sound')
-rw-r--r--src/sound/README.txt1
-rw-r--r--src/sound/oalsound/alsound.cpp517
-rw-r--r--src/sound/oalsound/alsound.h142
-rw-r--r--src/sound/oalsound/buffer.cpp69
-rw-r--r--src/sound/oalsound/buffer.h48
-rw-r--r--src/sound/oalsound/channel.cpp328
-rw-r--r--src/sound/oalsound/channel.h142
-rw-r--r--src/sound/oalsound/check.h1
-rw-r--r--src/sound/sound.cpp191
-rw-r--r--src/sound/sound.h110
10 files changed, 1024 insertions, 525 deletions
diff --git a/src/sound/README.txt b/src/sound/README.txt
index fa2f531..f0ccb9e 100644
--- a/src/sound/README.txt
+++ b/src/sound/README.txt
@@ -2,3 +2,4 @@
* \dir src/sound
* \brief Sound module - playing sounds and music
*/
+
diff --git a/src/sound/oalsound/alsound.cpp b/src/sound/oalsound/alsound.cpp
index 8c1cb81..992b8b2 100644
--- a/src/sound/oalsound/alsound.cpp
+++ b/src/sound/oalsound/alsound.cpp
@@ -16,18 +16,22 @@
// * along with this program. If not, see http://www.gnu.org/licenses/.
-#include "alsound.h"
+#include "sound/oalsound/alsound.h"
-#define MIN(a, b) (a > b ? b : a)
+#include <algorithm>
+#include <iomanip>
+
+#include <boost/filesystem.hpp>
ALSound::ALSound()
{
- mEnabled = false;
- m3D = false;
- mAudioVolume = 1.0f;
- mMusicVolume = 1.0f;
- mMute = false;
- mCurrentMusic = nullptr;
+ m_enabled = false;
+ m_3D = false;
+ m_audioVolume = 1.0f;
+ m_musicVolume = 1.0f;
+ m_currentMusic = nullptr;
+ m_eye.LoadZero();
+ m_lookat.LoadZero();
}
@@ -39,24 +43,36 @@ ALSound::~ALSound()
void ALSound::CleanUp()
{
- if (mEnabled) {
+ if (m_enabled)
+ {
GetLogger()->Info("Unloading files and closing device...\n");
StopAll();
+ StopMusic();
- for (auto channel : mChannels) {
+ for (auto channel : m_channels)
+ {
delete channel.second;
}
- for (auto item : mSounds) {
+ if (m_currentMusic)
+ {
+ delete m_currentMusic;
+ }
+
+ for (auto item : m_sounds)
+ {
delete item.second;
}
- mEnabled = false;
+ for (auto item : m_music)
+ {
+ delete item.second;
+ }
+
+ m_enabled = false;
- mCurrentMusic->FreeBuffer();
- delete mCurrentMusic;
- alcDestroyContext(mContext);
- alcCloseDevice(mDevice);
+ alcDestroyContext(m_context);
+ alcCloseDevice(m_device);
}
}
@@ -65,41 +81,43 @@ bool ALSound::Create(bool b3D)
{
CleanUp();
- if (mEnabled)
+ if (m_enabled)
return true;
GetLogger()->Info("Opening audio device...\n");
- mDevice = alcOpenDevice(NULL);
- if (!mDevice) {
+ m_device = alcOpenDevice(NULL);
+ if (!m_device)
+ {
GetLogger()->Error("Could not open audio device!\n");
return false;
}
- mContext = alcCreateContext(mDevice, NULL);
- if (!mContext) {
+ m_context = alcCreateContext(m_device, NULL);
+ if (!m_context)
+ {
GetLogger()->Error("Could not create audio context!\n");
return false;
}
- alcMakeContextCurrent(mContext);
+ alcMakeContextCurrent(m_context);
+ alListenerf(AL_GAIN, m_audioVolume);
+ alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
- mCurrentMusic = new Channel();
+ m_currentMusic = new Channel();
GetLogger()->Info("Done.\n");
- mEnabled = true;
+ m_enabled = true;
return true;
}
void ALSound::SetSound3D(bool bMode)
{
- // TODO stub! need to be implemented
- m3D = bMode;
+ m_3D = bMode;
}
bool ALSound::GetSound3D()
{
- // TODO stub! need to be implemented
- return true;
+ return m_3D;
}
@@ -112,54 +130,70 @@ bool ALSound::GetSound3DCap()
bool ALSound::GetEnable()
{
- return mEnabled;
+ return m_enabled;
}
void ALSound::SetAudioVolume(int volume)
{
- mAudioVolume = MIN(static_cast<float>(volume) / MAXVOLUME, 1.0f);
- alListenerf(AL_GAIN, mAudioVolume);
+ m_audioVolume = static_cast<float>(volume) / MAXVOLUME;
}
int ALSound::GetAudioVolume()
{
- if ( !mEnabled )
+ if ( !m_enabled )
return 0;
- return mAudioVolume * MAXVOLUME;
+ return m_audioVolume * MAXVOLUME;
}
void ALSound::SetMusicVolume(int volume)
{
- mMusicVolume = MIN(static_cast<float>(volume) / MAXVOLUME, 1.0f);
- if (mCurrentMusic) {
- mCurrentMusic->SetVolume(mMusicVolume * mAudioVolume);
+ m_musicVolume = static_cast<float>(volume) / MAXVOLUME;
+ if (m_currentMusic)
+ {
+ m_currentMusic->SetVolume(m_musicVolume);
}
}
int ALSound::GetMusicVolume()
{
- if ( !mEnabled )
+ if ( !m_enabled )
return 0.0f;
- return mMusicVolume * MAXVOLUME;
+ return m_musicVolume * MAXVOLUME;
}
bool ALSound::Cache(Sound sound, std::string filename)
{
Buffer *buffer = new Buffer();
- if (buffer->LoadFromFile(filename, sound)) {
- mSounds[sound] = buffer;
+ if (buffer->LoadFromFile(filename, sound))
+ {
+ m_sounds[sound] = buffer;
return true;
}
return false;
}
+bool ALSound::CacheMusic(std::string filename)
+{
+ if (m_music.find(filename) == m_music.end())
+ {
+ Buffer *buffer = new Buffer();
+ std::stringstream file;
+ file << m_soundPath << "/" << filename;
+ if (buffer->LoadFromFile(file.str(), static_cast<Sound>(-1)))
+ {
+ m_music[filename] = buffer;
+ return true;
+ }
+ }
+ return false;
+}
int ALSound::GetPriority(Sound sound)
{
@@ -215,7 +249,8 @@ bool ALSound::SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded)
int priority = GetPriority(sound);
// Seeks a channel used which sound is stopped.
- for (auto it : mChannels) {
+ for (auto it : m_channels)
+ {
if (it.second->IsPlaying())
continue;
if (it.second->GetSoundType() != sound)
@@ -228,47 +263,55 @@ bool ALSound::SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded)
}
// just add a new channel if we dont have any
- if (mChannels.size() == 0) {
+ if (m_channels.size() == 0)
+ {
Channel *chn = new Channel();
// check if we channel ready to play music, if not report error
- if (chn->IsReady()) {
+ if (chn->IsReady())
+ {
chn->SetPriority(priority);
- mChannels[1] = chn;
+ m_channels[1] = chn;
channel = 1;
bAlreadyLoaded = false;
return true;
}
delete chn;
- GetLogger()->Error("Could not open channel to play sound!");
+ GetLogger()->Error("Could not open channel to play sound!\n");
return false;
}
// Seeks a channel completely free.
- if (mChannels.size() < 64) {
- auto it = mChannels.end();
+ if (m_channels.size() < 64)
+ {
+ auto it = m_channels.end();
it--;
int i = (*it).first;
- while (++i) {
- if (mChannels.find(i) == mChannels.end()) {
+ while (++i)
+ {
+ if (m_channels.find(i) == m_channels.end())
+ {
Channel *chn = new Channel();
// check if channel is ready to play music, if not destroy it and seek free one
- if (chn->IsReady()) {
+ if (chn->IsReady())
+ {
chn->SetPriority(priority);
- mChannels[++i] = chn;
+ m_channels[++i] = chn;
channel = i;
bAlreadyLoaded = false;
return true;
}
delete chn;
- GetLogger()->Warn("Could not open additional channel to play sound!");
+ GetLogger()->Warn("Could not open additional channel to play sound!\n");
}
}
}
int lowerOrEqual = -1;
- for (auto it : mChannels) {
- if (it.second->GetPriority() < priority) {
- GetLogger()->Debug("Sound channel with lower priority will be reused.");
+ for (auto it : m_channels)
+ {
+ if (it.second->GetPriority() < priority)
+ {
+ GetLogger()->Debug("Sound channel with lower priority will be reused.\n");
channel = it.first;
return true;
}
@@ -276,9 +319,10 @@ bool ALSound::SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded)
lowerOrEqual = it.first;
}
- if (lowerOrEqual != -1) {
+ if (lowerOrEqual != -1)
+ {
channel = lowerOrEqual;
- GetLogger()->Debug("Sound channel with lower or equal priority will be reused.");
+ GetLogger()->Debug("Sound channel with lower or equal priority will be reused.\n");
return true;
}
@@ -289,17 +333,18 @@ bool ALSound::SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded)
int ALSound::Play(Sound sound, float amplitude, float frequency, bool bLoop)
{
- return Play(sound, Math::Vector(), amplitude, frequency, bLoop);
+ return Play(sound, m_eye, amplitude, frequency, bLoop);
}
int ALSound::Play(Sound sound, Math::Vector pos, float amplitude, float frequency, bool bLoop)
{
- if (!mEnabled) {
+ if (!m_enabled)
+ {
return -1;
}
-
- if (mSounds.find(sound) == mSounds.end()) {
+ if (m_sounds.find(sound) == m_sounds.end())
+ {
GetLogger()->Warn("Sound %d was not loaded!\n", sound);
return -1;
}
@@ -309,23 +354,34 @@ int ALSound::Play(Sound sound, Math::Vector pos, float amplitude, float frequenc
if (!SearchFreeBuffer(sound, channel, bAlreadyLoaded))
return -1;
- if (!bAlreadyLoaded) {
- if (!mChannels[channel]->SetBuffer(mSounds[sound])) {
- mChannels[channel]->SetBuffer(nullptr);
+ if (!bAlreadyLoaded)
+ {
+ if (!m_channels[channel]->SetBuffer(m_sounds[sound]))
+ {
+ m_channels[channel]->SetBuffer(nullptr);
return -1;
}
}
+
Position(channel, pos);
+ if (!m_3D)
+ {
+ ComputeVolumePan2D(channel, pos);
+ }
+ else
+ {
+ m_channels[channel]->SetVolumeAtrib(1.0f);
+ }
// setting initial values
- mChannels[channel]->SetStartAmplitude(amplitude);
- mChannels[channel]->SetStartFrequency(frequency);
- mChannels[channel]->SetChangeFrequency(1.0f);
- mChannels[channel]->ResetOper();
- mChannels[channel]->SetFrequency(frequency);
- mChannels[channel]->SetVolume(amplitude * mAudioVolume);
- mChannels[channel]->SetLoop(bLoop);
- mChannels[channel]->Play();
+ m_channels[channel]->SetStartAmplitude(amplitude);
+ m_channels[channel]->SetStartFrequency(frequency);
+ m_channels[channel]->SetChangeFrequency(1.0f);
+ m_channels[channel]->ResetOper();
+ m_channels[channel]->SetFrequency(frequency);
+ m_channels[channel]->SetVolume(powf(amplitude * m_channels[channel]->GetVolumeAtrib(), 0.2f) * m_audioVolume);
+ m_channels[channel]->SetLoop(bLoop);
+ m_channels[channel]->Play();
return channel;
}
@@ -333,31 +389,33 @@ int ALSound::Play(Sound sound, Math::Vector pos, float amplitude, float frequenc
bool ALSound::FlushEnvelope(int channel)
{
- if (mChannels.find(channel) == mChannels.end()) {
+ if (m_channels.find(channel) == m_channels.end())
+ {
return false;
}
- mChannels[channel]->ResetOper();
+ m_channels[channel]->ResetOper();
return true;
}
bool ALSound::AddEnvelope(int channel, float amplitude, float frequency, float time, SoundNext oper)
{
- if (!mEnabled)
+ if (!m_enabled)
return false;
- if (mChannels.find(channel) == mChannels.end()) {
+ if (m_channels.find(channel) == m_channels.end())
+ {
return false;
}
-
+
SoundOper op;
op.finalAmplitude = amplitude;
op.finalFrequency = frequency;
op.totalTime = time;
op.nextOper = oper;
op.currentTime = 0.0f;
- mChannels[channel]->AddOper(op);
+ m_channels[channel]->AddOper(op);
return true;
}
@@ -365,43 +423,59 @@ bool ALSound::AddEnvelope(int channel, float amplitude, float frequency, float t
bool ALSound::Position(int channel, Math::Vector pos)
{
- if (!mEnabled)
+ if (!m_enabled)
return false;
- if (mChannels.find(channel) == mChannels.end()) {
+ if (m_channels.find(channel) == m_channels.end())
+ {
return false;
}
- mChannels[channel]->SetPosition(pos);
+ if (m_3D)
+ {
+ m_channels[channel]->SetPan(pos);
+ }
+ else
+ {
+ ComputeVolumePan2D(channel, pos);
+
+ if (!m_channels[channel]->HasEnvelope())
+ {
+ float volume = m_channels[channel]->GetStartAmplitude();
+ m_channels[channel]->SetVolume(powf(volume * m_channels[channel]->GetVolumeAtrib(), 0.2f) * m_audioVolume);
+ }
+ }
return true;
}
bool ALSound::Frequency(int channel, float frequency)
{
- if (!mEnabled)
+ if (!m_enabled)
return false;
- if (mChannels.find(channel) == mChannels.end()) {
+ if (m_channels.find(channel) == m_channels.end())
+ {
return false;
}
- mChannels[channel]->SetFrequency(frequency * mChannels[channel]->GetInitFrequency());
- mChannels[channel]->SetChangeFrequency(frequency);
+ m_channels[channel]->SetFrequency(frequency * m_channels[channel]->GetInitFrequency());
+ m_channels[channel]->SetChangeFrequency(frequency);
return true;
}
bool ALSound::Stop(int channel)
{
- if (!mEnabled)
+ if (!m_enabled)
return false;
- if (mChannels.find(channel) == mChannels.end()) {
+ if (m_channels.find(channel) == m_channels.end())
+ {
return false;
}
- mChannels[channel]->Stop();
- mChannels[channel]->ResetOper();
+ m_channels[channel]->Stop();
+ m_channels[channel]->ResetOper();
return true;
}
@@ -409,10 +483,11 @@ bool ALSound::Stop(int channel)
bool ALSound::StopAll()
{
- if (!mEnabled)
+ if (!m_enabled)
return false;
- for (auto channel : mChannels) {
+ for (auto channel : m_channels)
+ {
channel.second->Stop();
channel.second->ResetOper();
}
@@ -423,32 +498,46 @@ bool ALSound::StopAll()
bool ALSound::MuteAll(bool bMute)
{
- if (!mEnabled)
+ if (!m_enabled)
return false;
- float volume;
- mMute = bMute;
- if (mMute)
- volume = 0;
- else
- volume = mAudioVolume;
-
- for (auto channel : mChannels) {
- channel.second->SetVolume(volume * mAudioVolume);
+ for (auto it : m_channels)
+ {
+ if (it.second->IsPlaying())
+ {
+ it.second->Mute(bMute);
+ }
}
+ if (bMute)
+ {
+ m_currentMusic->SetVolume(0.0f);
+ }
+ else
+ {
+ m_currentMusic->SetVolume(m_musicVolume);
+ }
return true;
}
+
void ALSound::FrameMove(float delta)
{
- if (!mEnabled)
+ if (!m_enabled)
return;
float progress;
float volume, frequency;
- for (auto it : mChannels) {
- if (!it.second->IsPlaying()) {
+ for (auto it : m_channels)
+ {
+ if (!it.second->IsPlaying())
+ {
+ continue;
+ }
+
+ if (it.second->IsMuted())
+ {
+ it.second->SetVolume(0.0f);
continue;
}
@@ -458,25 +547,34 @@ void ALSound::FrameMove(float delta)
SoundOper &oper = it.second->GetEnvelope();
oper.currentTime += delta;
progress = oper.currentTime / oper.totalTime;
- progress = MIN(progress, 1.0f);
-
+ progress = std::min(progress, 1.0f);
+
// setting volume
volume = progress * (oper.finalAmplitude - it.second->GetStartAmplitude());
- volume = (volume + it.second->GetStartAmplitude()) * mAudioVolume;
- it.second->SetVolume(volume);
+ volume = volume + it.second->GetStartAmplitude();
+ it.second->SetVolume(powf(volume * it.second->GetVolumeAtrib(), 0.2f) * m_audioVolume);
// setting frequency
- frequency = progress * (oper.finalFrequency - it.second->GetStartFrequency()) * it.second->GetStartFrequency() * it.second->GetChangeFrequency() * it.second->GetInitFrequency();
- it.second->AdjustFrequency(frequency);
-
- if (oper.totalTime <= oper.currentTime) {
- if (oper.nextOper == SOPER_LOOP) {
+ frequency = progress;
+ frequency *= oper.finalFrequency - it.second->GetStartFrequency();
+ frequency += it.second->GetStartFrequency();
+ frequency *= it.second->GetChangeFrequency();
+ frequency = (frequency * it.second->GetInitFrequency());
+ it.second->SetFrequency(frequency);
+
+ if (oper.totalTime <= oper.currentTime)
+ {
+ if (oper.nextOper == SOPER_LOOP)
+ {
oper.currentTime = 0.0f;
it.second->Play();
- } else {
+ }
+ else
+ {
it.second->SetStartAmplitude(oper.finalAmplitude);
it.second->SetStartFrequency(oper.finalFrequency);
- if (oper.nextOper == SOPER_STOP) {
+ if (oper.nextOper == SOPER_STOP)
+ {
it.second->Stop();
}
@@ -489,94 +587,185 @@ void ALSound::FrameMove(float delta)
void ALSound::SetListener(Math::Vector eye, Math::Vector lookat)
{
- float orientation[] = {lookat.x, lookat.y, lookat.z, 0.f, 1.f, 0.f};
- alListener3f(AL_POSITION, eye.x, eye.y, eye.z);
- alListenerfv(AL_ORIENTATION, orientation);
+ m_eye = eye;
+ m_lookat = lookat;
+ if (m_3D)
+ {
+ float orientation[] = {lookat.x, lookat.y, lookat.z, 0.f, 1.f, 0.f};
+ alListener3f(AL_POSITION, eye.x, eye.y, eye.z);
+ alListenerfv(AL_ORIENTATION, orientation);
+ }
+ else
+ {
+ 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 : m_channels)
+ {
+ 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) * m_audioVolume);
+ }
+ }
+ }
+ }
}
-
bool ALSound::PlayMusic(int rank, bool bRepeat)
{
- if (!mEnabled) {
+ std::stringstream filename;
+ filename << "music" << std::setfill('0') << std::setw(3) << rank << ".ogg";
+ return PlayMusic(filename.str(), bRepeat);
+}
+
+bool ALSound::PlayMusic(std::string filename, bool bRepeat)
+{
+ if (!m_enabled)
+ {
return false;
}
-
- if (static_cast<int>(mCurrentMusic->GetSoundType()) != rank) {
- // check if we have music in cache
- for (auto music : mMusicCache) {
- if (static_cast<int>(music->GetSoundType()) == rank) {
- GetLogger()->Debug("Music loaded from cache\n");
- mCurrentMusic->SetBuffer(music);
-
- mCurrentMusic->SetVolume(mMusicVolume * mAudioVolume);
- mCurrentMusic->SetLoop(bRepeat);
- mCurrentMusic->Play();
- return true;
- }
- }
-
- // we cache only 3 music files
- if (mMusicCache.size() == 3) {
- mCurrentMusic->FreeBuffer();
- mMusicCache.pop_back();
- }
- if (mMusic.find(rank) == mMusic.end()) {
- GetLogger()->Info("Requested music %d was not found.\n", rank);
+ std::stringstream file;
+ file << m_soundPath << "/" << filename;
+
+ // check if we have music in cache
+ if (m_music.find(filename) == m_music.end())
+ {
+ GetLogger()->Warn("Music %s was not cached!\n", filename.c_str());
+ if (!boost::filesystem::exists(file.str()))
+ {
+ GetLogger()->Warn("Requested music %s was not found.\n", filename.c_str());
return false;
}
-
Buffer *buffer = new Buffer();
- mMusicCache.push_front(buffer);
- buffer->LoadFromFile(mMusic.at(rank), static_cast<Sound>(rank));
- mCurrentMusic->SetBuffer(buffer);
- mMusicCache[rank] = buffer;
- }
-
- mCurrentMusic->SetVolume(mMusicVolume * mAudioVolume);
- mCurrentMusic->SetLoop(bRepeat);
- mCurrentMusic->Play();
-
+ buffer->LoadFromFile(file.str(), static_cast<Sound>(-1));
+ m_currentMusic->SetBuffer(buffer);
+ }
+ else
+ {
+ GetLogger()->Debug("Music loaded from cache\n");
+ m_currentMusic->SetBuffer(m_music[filename]);
+ }
+
+ m_currentMusic->SetVolume(m_musicVolume);
+ m_currentMusic->SetLoop(bRepeat);
+ m_currentMusic->Play();
+
return true;
}
bool ALSound::RestartMusic()
{
- if (!mEnabled || !mCurrentMusic) {
+ if (!m_enabled || !m_currentMusic)
+ {
return false;
}
- mCurrentMusic->Stop();
- mCurrentMusic->Play();
+ m_currentMusic->Stop();
+ m_currentMusic->Play();
return true;
}
void ALSound::StopMusic()
{
- if (!mEnabled || !mCurrentMusic) {
+ if (!m_enabled || !m_currentMusic)
+ {
return;
}
-
+
SuspendMusic();
}
bool ALSound::IsPlayingMusic()
{
- if (!mEnabled || !mCurrentMusic) {
+ if (!m_enabled || !m_currentMusic)
+ {
return false;
}
-
- return mCurrentMusic->IsPlaying();
+
+ return m_currentMusic->IsPlaying();
}
void ALSound::SuspendMusic()
{
- if (!mEnabled || !mCurrentMusic) {
+ if (!m_enabled || !m_currentMusic)
+ {
+ return;
+ }
+
+ m_currentMusic->Stop();
+}
+
+
+void ALSound::ComputeVolumePan2D(int channel, Math::Vector &pos)
+{
+ float dist, a, g;
+ m_channels[channel]->SetPosition(pos);
+
+ if (VectorsEqual(pos, m_eye))
+ {
+ m_channels[channel]->SetVolumeAtrib(1.0f); // maximum volume
+ m_channels[channel]->SetPan(Math::Vector()); // at the center
return;
}
-
- mCurrentMusic->Stop();
+
+ dist = Distance(pos, m_eye);
+ if ( dist >= 110.0f ) // very far?
+ {
+ m_channels[channel]->SetVolumeAtrib(0.0f); // silence
+ m_channels[channel]->SetPan(Math::Vector()); // at the center
+ return;
+ }
+ else if ( dist <= 10.0f ) // very close?
+ {
+ m_channels[channel]->SetVolumeAtrib(1.0f); // maximum volume
+ m_channels[channel]->SetPan(Math::Vector()); // at the center
+ return;
+ }
+ m_channels[channel]->SetVolumeAtrib(1.0f - ((dist - 10.0f) / 100.0f));
+
+ Math::Vector one = Math::Vector(1.0f, 0.0f, 0.0f);
+ float angle_a = Angle(Math::Vector(m_lookat.x - m_eye.x, m_lookat.z - m_eye.z, 0.0f), one);
+ float angle_g = Angle(Math::Vector(pos.x - m_eye.x, pos.z - m_eye.z, 0.0f), one);
+
+ a = fmodf(angle_a, Math::PI * 2.0f);
+ g = fmodf(angle_g, 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;
+ }
+ }
+
+ m_channels[channel]->SetPan( Math::Vector(0.0f, 0.0f, sinf(g - a)) );
}
+
diff --git a/src/sound/oalsound/alsound.h b/src/sound/oalsound/alsound.h
index bdf06b1..ad32204 100644
--- a/src/sound/oalsound/alsound.h
+++ b/src/sound/oalsound/alsound.h
@@ -15,82 +15,90 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
-// alsound.h
+/**
+ * \file alsound.h
+ * \brief OpenAL implementation of sound system
+ */
#pragma once
+#include "common/logger.h"
+#include "sound/sound.h"
+
+#include "sound/oalsound/buffer.h"
+#include "sound/oalsound/channel.h"
+#include "sound/oalsound/check.h"
+
#include <map>
#include <string>
#include <AL/al.h>
-#include "common/logger.h"
-#include "sound/sound.h"
-
-#include "buffer.h"
-#include "channel.h"
-#include "check.h"
-
class ALSound : public CSoundInterface
{
- public:
- ALSound();
- ~ALSound();
-
- bool Create(bool b3D);
- bool Cache(Sound, std::string);
-
- bool GetEnable();
-
- void SetSound3D(bool bMode);
- bool GetSound3D();
- bool GetSound3DCap();
-
- void SetAudioVolume(int volume);
- int GetAudioVolume();
- void SetMusicVolume(int volume);
- int GetMusicVolume();
-
- void SetListener(Math::Vector eye, Math::Vector lookat);
- void FrameMove(float rTime);
-
- int Play(Sound sound, float amplitude=1.0f, float frequency=1.0f, bool bLoop = false);
- int Play(Sound sound, Math::Vector pos, float amplitude=1.0f, float frequency=1.0f, bool bLoop = false);
- bool FlushEnvelope(int channel);
- bool AddEnvelope(int channel, float amplitude, float frequency, float time, SoundNext oper);
- bool Position(int channel, Math::Vector pos);
- bool Frequency(int channel, float frequency);
- bool Stop(int channel);
- bool StopAll();
- bool MuteAll(bool bMute);
-
- bool PlayMusic(int rank, bool bRepeat);
- bool RestartMusic();
- void SuspendMusic();
- void StopMusic();
- bool IsPlayingMusic();
-
- // plugin interface
- std::string PluginName();
- int PluginVersion();
- void InstallPlugin();
- bool UninstallPlugin(std::string &);
-
- private:
- void CleanUp();
- int GetPriority(Sound);
- bool SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded);
-
- bool mEnabled;
- bool m3D;
- bool mMute;
- float mAudioVolume;
- float mMusicVolume;
- ALCdevice* mDevice;
- ALCcontext* mContext;
- std::map<Sound, Buffer*> mSounds;
- std::map<int, Channel*> mChannels;
- std::deque<Buffer*> mMusicCache;
- Channel *mCurrentMusic;
+public:
+ ALSound();
+ ~ALSound();
+
+ bool Create(bool b3D);
+ bool Cache(Sound, std::string);
+ bool CacheMusic(std::string);
+
+ bool GetEnable();
+
+ void SetSound3D(bool bMode);
+ bool GetSound3D();
+ bool GetSound3DCap();
+
+ void SetAudioVolume(int volume);
+ int GetAudioVolume();
+ void SetMusicVolume(int volume);
+ int GetMusicVolume();
+
+ void SetListener(Math::Vector eye, Math::Vector lookat);
+ void FrameMove(float rTime);
+
+ int Play(Sound sound, float amplitude=1.0f, float frequency=1.0f, bool bLoop = false);
+ int Play(Sound sound, Math::Vector pos, float amplitude=1.0f, float frequency=1.0f, bool bLoop = false);
+ bool FlushEnvelope(int channel);
+ bool AddEnvelope(int channel, float amplitude, float frequency, float time, SoundNext oper);
+ bool Position(int channel, Math::Vector pos);
+ bool Frequency(int channel, float frequency);
+ bool Stop(int channel);
+ bool StopAll();
+ bool MuteAll(bool bMute);
+
+ bool PlayMusic(int rank, bool bRepeat);
+ bool PlayMusic(std::string filename, bool bRepeat);
+ bool RestartMusic();
+ void SuspendMusic();
+ void StopMusic();
+ bool IsPlayingMusic();
+
+ // plugin interface
+ std::string PluginName();
+ int PluginVersion();
+ void InstallPlugin();
+ bool UninstallPlugin(std::string &);
+
+private:
+ void CleanUp();
+ int GetPriority(Sound);
+ bool SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded);
+ void ComputeVolumePan2D(int channel, Math::Vector &pos);
+
+ bool m_enabled;
+ bool m_3D;
+ float m_audioVolume;
+ float m_musicVolume;
+ ALCdevice* m_device;
+ ALCcontext* m_context;
+ std::map<Sound, Buffer*> m_sounds;
+ std::map<std::string, Buffer*> m_music;
+ std::map<int, Channel*> m_channels;
+ Channel *m_currentMusic;
+ Math::Vector m_eye;
+ Math::Vector m_lookat;
};
+
diff --git a/src/sound/oalsound/buffer.cpp b/src/sound/oalsound/buffer.cpp
index edc3d74..0047f91 100644
--- a/src/sound/oalsound/buffer.cpp
+++ b/src/sound/oalsound/buffer.cpp
@@ -15,28 +15,35 @@
// * along with this program. If not, see http://www.gnu.org/licenses/.
-#include "buffer.h"
+#include "sound/oalsound/buffer.h"
-Buffer::Buffer() {
- mLoaded = false;
- mDuration = 0.0f;
+#include <cstring>
+
+Buffer::Buffer()
+{
+ m_loaded = false;
+ m_duration = 0.0f;
}
-Buffer::~Buffer() {
- if (mLoaded) {
- alDeleteBuffers(1, &mBuffer);
+Buffer::~Buffer()
+{
+ if (m_loaded)
+ {
+ alDeleteBuffers(1, &m_buffer);
if (alCheck())
GetLogger()->Warn("Failed to unload buffer. Code %d\n", alGetCode());
}
}
-bool Buffer::LoadFromFile(std::string filename, Sound sound) {
- mSound = sound;
+bool Buffer::LoadFromFile(std::string filename, Sound sound)
+{
+ m_sound = sound;
GetLogger()->Debug("Loading audio file: %s\n", filename.c_str());
SF_INFO fileInfo;
+ memset(&fileInfo, 0, sizeof(SF_INFO));
SNDFILE *file = sf_open(filename.c_str(), SFM_READ, &fileInfo);
GetLogger()->Trace(" channels %d\n", fileInfo.channels);
@@ -45,16 +52,18 @@ bool Buffer::LoadFromFile(std::string filename, Sound sound) {
GetLogger()->Trace(" samplerate %d\n", fileInfo.samplerate);
GetLogger()->Trace(" sections %d\n", fileInfo.sections);
- if (!file) {
+ if (!file)
+ {
GetLogger()->Warn("Could not load file. Reason: %s\n", sf_strerror(file));
- mLoaded = false;
+ m_loaded = false;
return false;
}
- alGenBuffers(1, &mBuffer);
- if (!mBuffer) {
+ alGenBuffers(1, &m_buffer);
+ if (!m_buffer)
+ {
GetLogger()->Warn("Could not create audio buffer\n");
- mLoaded = false;
+ m_loaded = false;
sf_close(file);
return false;
}
@@ -64,33 +73,39 @@ bool Buffer::LoadFromFile(std::string filename, Sound sound) {
std::array<int16_t, 4096> buffer;
data.reserve(fileInfo.frames);
size_t read = 0;
- while ((read = sf_read_short(file, buffer.data(), buffer.size())) != 0) {
+ while ((read = sf_read_short(file, buffer.data(), buffer.size())) != 0)
+ {
data.insert(data.end(), buffer.begin(), buffer.begin() + read);
}
- sf_close(file);
+ sf_close(file);
- alBufferData(mBuffer, fileInfo.channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, &data.front(), data.size() * sizeof(uint16_t), fileInfo.samplerate);
- mDuration = static_cast<float>(fileInfo.frames) / fileInfo.samplerate;
- mLoaded = true;
+ alBufferData(m_buffer, fileInfo.channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, &data.front(), data.size() * sizeof(uint16_t), fileInfo.samplerate);
+ m_duration = static_cast<float>(fileInfo.frames) / fileInfo.samplerate;
+ m_loaded = true;
return true;
}
-Sound Buffer::GetSoundType() {
- return mSound;
+Sound Buffer::GetSoundType()
+{
+ return m_sound;
}
-ALuint Buffer::GetBuffer() {
- return mBuffer;
+ALuint Buffer::GetBuffer()
+{
+ return m_buffer;
}
-bool Buffer::IsLoaded() {
- return mLoaded;
+bool Buffer::IsLoaded()
+{
+ return m_loaded;
}
-float Buffer::GetDuration() {
- return mDuration;
+float Buffer::GetDuration()
+{
+ return m_duration;
}
+
diff --git a/src/sound/oalsound/buffer.h b/src/sound/oalsound/buffer.h
index 7286deb..d847426 100644
--- a/src/sound/oalsound/buffer.h
+++ b/src/sound/oalsound/buffer.h
@@ -14,10 +14,18 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
-// buffer.h
+/**
+ * \file buffer.h
+ * \brief OpenAL buffer
+ */
#pragma once
+#include "sound/sound.h"
+#include "common/logger.h"
+
+#include "sound/oalsound/check.h"
+
#include <string>
#include <vector>
#include <array>
@@ -25,27 +33,23 @@
#include <AL/al.h>
#include <sndfile.h>
-#include "sound/sound.h"
-#include "common/logger.h"
-
-#include "check.h"
-
class Buffer
{
- public:
- Buffer();
- ~Buffer();
-
- bool LoadFromFile(std::string, Sound);
- bool IsLoaded();
-
- Sound GetSoundType();
- ALuint GetBuffer();
- float GetDuration();
-
- private:
- ALuint mBuffer;
- Sound mSound;
- bool mLoaded;
- float mDuration;
+public:
+ Buffer();
+ ~Buffer();
+
+ bool LoadFromFile(std::string, Sound);
+ bool IsLoaded();
+
+ Sound GetSoundType();
+ ALuint GetBuffer();
+ float GetDuration();
+
+private:
+ ALuint m_buffer;
+ Sound m_sound;
+ bool m_loaded;
+ float m_duration;
};
+
diff --git a/src/sound/oalsound/channel.cpp b/src/sound/oalsound/channel.cpp
index 19394c6..4d89df5 100644
--- a/src/sound/oalsound/channel.cpp
+++ b/src/sound/oalsound/channel.cpp
@@ -15,59 +15,76 @@
// * along with this program. If not, see http://www.gnu.org/licenses/.
-#include "channel.h"
+#include "sound/oalsound/channel.h"
-#define MIN(a, b) (a > b ? b : a)
-
-Channel::Channel() {
- alGenSources(1, &mSource);
+Channel::Channel()
+{
+ alGenSources(1, &m_source);
- if (alCheck()) {
+ if (alCheck())
+ {
GetLogger()->Warn("Failed to create sound source. Code: %d\n", alGetCode());
- mReady = false;
- } else {
- mReady = true;
+ m_ready = false;
}
-
- mPriority = 0;
- mBuffer = nullptr;
- mLoop = false;
- mInitFrequency = 0.0f;
- mStartAmplitude = 0.0f;
- mStartFrequency = 0.0f;
- mChangeFrequency = 0.0f;
-}
-
-
-Channel::~Channel() {
- if (mReady) {
- alSourceStop(mSource);
- alSourcei(mSource, AL_BUFFER, 0);
- alDeleteSources(1, &mSource);
+ else
+ {
+ m_ready = true;
+ }
+
+ m_priority = 0;
+ m_buffer = nullptr;
+ m_loop = false;
+ m_mute = false;
+ m_initFrequency = 0.0f;
+ m_startAmplitude = 0.0f;
+ m_startFrequency = 0.0f;
+ m_changeFrequency = 0.0f;
+ m_volume = 0.0f;
+}
+
+
+Channel::~Channel()
+{
+ if (m_ready)
+ {
+ alSourceStop(m_source);
+ alSourcei(m_source, AL_BUFFER, 0);
+ alDeleteSources(1, &m_source);
if (alCheck())
GetLogger()->Warn("Failed to delete sound source. Code: %d\n", alGetCode());
}
}
-bool Channel::Play() {
- if (!mReady || mBuffer == nullptr)
+bool Channel::Play()
+{
+ if (!m_ready || m_buffer == nullptr)
+ {
return false;
+ }
- alSourcei(mSource, AL_LOOPING, static_cast<ALint>(mLoop));
- alSourcePlay(mSource);
+ alSourcei(m_source, AL_LOOPING, static_cast<ALint>(m_loop));
+ alSourcei(m_source, AL_REFERENCE_DISTANCE, 10.0f);
+ alSourcei(m_source, AL_MAX_DISTANCE, 110.0f);
+ alSourcePlay(m_source);
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)
+bool Channel::SetPan(Math::Vector pos)
+{
+ if (!m_ready || m_buffer == nullptr)
+ {
return false;
-
- alSource3f(mSource, AL_POSITION, pos.x, pos.y, pos.z);
- if (alCheck()) {
+ }
+
+ alSource3f(m_source, AL_POSITION, pos.x, pos.y, pos.z);
+ if (alCheck())
+ {
GetLogger()->Warn("Could not set sound position. Code: %d\n", alGetCode());
return false;
}
@@ -75,37 +92,46 @@ bool Channel::SetPosition(Math::Vector pos) {
}
-bool Channel::SetFrequency(float freq)
+void Channel::SetPosition(Math::Vector pos)
{
- if (!mReady || mBuffer == nullptr)
- return false;
+ m_position = pos;
+}
- alSourcef(mSource, AL_PITCH, freq);
- if (alCheck()) {
- GetLogger()->Warn("Could not set sound pitch to '%f'. Code: %d\n", freq, alGetCode());
- return false;
- }
- return true;
+
+Math::Vector Channel::GetPosition()
+{
+ return m_position;
}
-bool Channel::AdjustFrequency(float freq)
+bool Channel::SetFrequency(float freq)
{
- if (!mReady || mBuffer == nullptr)
+ if (!m_ready || m_buffer == nullptr)
+ {
return false;
+ }
- return SetFrequency(mInitFrequency + fabs(freq));
+ alSourcef(m_source, AL_PITCH, freq);
+ if (alCheck())
+ {
+ GetLogger()->Warn("Could not set sound pitch to '%f'. Code: %d\n", freq, alGetCode());
+ return false;
+ }
+ return true;
}
float Channel::GetFrequency()
{
ALfloat freq;
- if (!mReady || mBuffer == nullptr)
+ if (!m_ready || m_buffer == nullptr)
+ {
return 0;
-
- alGetSourcef(mSource, AL_PITCH, &freq);
- if (alCheck()) {
+ }
+
+ alGetSourcef(m_source, AL_PITCH, &freq);
+ if (alCheck())
+ {
GetLogger()->Warn("Could not get sound pitch. Code: %d\n", alGetCode());
return 0;
}
@@ -116,11 +142,14 @@ float Channel::GetFrequency()
bool Channel::SetVolume(float vol)
{
- if (!mReady || vol < 0 || mBuffer == nullptr)
+ if (!m_ready || vol < 0 || m_buffer == nullptr)
+ {
return false;
-
- alSourcef(mSource, AL_GAIN, MIN(powf(vol, 0.2f), 1.0f));
- if (alCheck()) {
+ }
+
+ alSourcef(m_source, AL_GAIN, vol);
+ if (alCheck())
+ {
GetLogger()->Warn("Could not set sound volume to '%f'. Code: %d\n", vol, alGetCode());
return false;
}
@@ -131,11 +160,14 @@ bool Channel::SetVolume(float vol)
float Channel::GetVolume()
{
ALfloat vol;
- if (!mReady || mBuffer == nullptr)
+ if (!m_ready || m_buffer == nullptr)
+ {
return 0;
-
- alGetSourcef(mSource, AL_GAIN, &vol);
- if (alCheck()) {
+ }
+
+ alGetSourcef(m_source, AL_GAIN, &vol);
+ if (alCheck())
+ {
GetLogger()->Warn("Could not get sound volume. Code: %d\n", alGetCode());
return 0;
}
@@ -144,125 +176,146 @@ float Channel::GetVolume()
}
+void Channel::SetVolumeAtrib(float volume)
+{
+ m_volume = volume;
+}
+
+
+float Channel::GetVolumeAtrib()
+{
+ return m_volume;
+}
+
+
+
int Channel::GetPriority()
{
- return mPriority;
+ return m_priority;
}
void Channel::SetPriority(int pri)
{
- mPriority = pri;
+ m_priority = pri;
}
void Channel::SetStartAmplitude(float gain)
{
- mStartAmplitude = gain;
- SetVolume(mStartAmplitude);
+ m_startAmplitude = gain;
}
void Channel::SetStartFrequency(float freq)
{
- mStartFrequency = freq;
+ m_startFrequency = freq;
}
void Channel::SetChangeFrequency(float freq)
{
- mChangeFrequency = freq;
+ m_changeFrequency = freq;
}
float Channel::GetStartAmplitude()
{
- return mStartAmplitude;
+ return m_startAmplitude;
}
float Channel::GetStartFrequency()
{
- return mStartFrequency;
+ return m_startFrequency;
}
float Channel::GetChangeFrequency()
{
- return mChangeFrequency;
+ return m_changeFrequency;
}
float Channel::GetInitFrequency()
{
- return mInitFrequency;
+ return m_initFrequency;
}
void Channel::AddOper(SoundOper oper)
{
- mOper.push_back(oper);
+ m_oper.push_back(oper);
}
void Channel::ResetOper()
{
- mOper.clear();
+ m_oper.clear();
}
-Sound Channel::GetSoundType() {
- if (!mReady || mBuffer == nullptr)
+Sound Channel::GetSoundType()
+{
+ if (!m_ready || m_buffer == nullptr)
+ {
return SOUND_NONE;
-
- return mBuffer->GetSoundType();
+ }
+
+ return m_buffer->GetSoundType();
}
-bool Channel::SetBuffer(Buffer *buffer) {
- if (!mReady)
+bool Channel::SetBuffer(Buffer *buffer)
+{
+ if (!m_ready)
return false;
- Stop();
- mBuffer = buffer;
- if (buffer == nullptr) {
- alSourcei(mSource, AL_BUFFER, 0);
+ Stop();
+ m_buffer = buffer;
+ if (buffer == nullptr)
+ {
+ alSourcei(m_source, AL_BUFFER, 0);
return true;
- }
-
- alSourcei(mSource, AL_BUFFER, buffer->GetBuffer());
- if (alCheck()) {
+ }
+
+ alSourcei(m_source, AL_BUFFER, buffer->GetBuffer());
+ if (alCheck())
+ {
GetLogger()->Warn("Could not set sound buffer. Code: %d\n", alGetCode());
return false;
}
- mInitFrequency = GetFrequency();
+ m_initFrequency = GetFrequency();
return true;
}
-bool Channel::FreeBuffer() {
- if (!mReady)
- return false;
-
- if (!mBuffer) {
+bool Channel::FreeBuffer()
+{
+ if (!m_ready || !m_buffer)
+ {
return false;
}
- alSourceStop(mSource);
- alSourcei(mSource, AL_BUFFER, 0);
- delete mBuffer;
- mBuffer = nullptr;
+ alSourceStop(m_source);
+ alSourcei(m_source, AL_BUFFER, 0);
+ delete m_buffer;
+ m_buffer = nullptr;
return true;
}
-bool Channel::IsPlaying() {
+bool Channel::IsPlaying()
+{
ALint status;
- if (!mReady || mBuffer == nullptr)
+ if (!m_ready || m_buffer == nullptr)
+ {
return false;
-
- alGetSourcei(mSource, AL_SOURCE_STATE, &status);
- if (alCheck()) {
+ }
+
+ alGetSourcei(m_source, AL_SOURCE_STATE, &status);
+ if (alCheck())
+ {
GetLogger()->Warn("Could not get sound status. Code: %d\n", alGetCode());
return false;
}
@@ -271,21 +324,27 @@ bool Channel::IsPlaying() {
}
-bool Channel::IsReady() {
- return mReady;
+bool Channel::IsReady()
+{
+ return m_ready;
}
-bool Channel::IsLoaded() {
- return mBuffer != nullptr;
+bool Channel::IsLoaded()
+{
+ return m_buffer != nullptr;
}
-bool Channel::Stop() {
- if (!mReady || mBuffer == nullptr)
+bool Channel::Stop()
+{
+ if (!m_ready || m_buffer == nullptr)
+ {
return false;
-
- alSourceStop(mSource);
- if (alCheck()) {
+ }
+
+ alSourceStop(m_source);
+ if (alCheck())
+ {
GetLogger()->Warn("Could not stop sound. Code: %d\n", alGetCode());
return false;
}
@@ -295,12 +354,15 @@ bool Channel::Stop() {
float Channel::GetCurrentTime()
{
- if (!mReady || mBuffer == nullptr)
+ if (!m_ready || m_buffer == nullptr)
+ {
return 0.0f;
-
+ }
+
ALfloat current;
- alGetSourcef(mSource, AL_SEC_OFFSET, &current);
- if (alCheck()) {
+ alGetSourcef(m_source, AL_SEC_OFFSET, &current);
+ if (alCheck())
+ {
GetLogger()->Warn("Could not get source current play time. Code: %d\n", alGetCode());
return 0.0f;
}
@@ -310,42 +372,62 @@ float Channel::GetCurrentTime()
void Channel::SetCurrentTime(float current)
{
- if (!mReady || mBuffer == nullptr)
+ if (!m_ready || m_buffer == nullptr)
+ {
return;
-
- alSourcef(mSource, AL_SEC_OFFSET, current);
+ }
+
+ alSourcef(m_source, AL_SEC_OFFSET, current);
if (alCheck())
+ {
GetLogger()->Warn("Could not get source current play time. Code: %d\n", alGetCode());
+ }
}
float Channel::GetDuration()
{
- if (!mReady || mBuffer == nullptr)
+ if (!m_ready || m_buffer == nullptr)
+ {
return 0.0f;
-
- return mBuffer->GetDuration();
+ }
+
+ return m_buffer->GetDuration();
}
bool Channel::HasEnvelope()
{
- return mOper.size() > 0;
+ return m_oper.size() > 0;
}
SoundOper& Channel::GetEnvelope()
{
- return mOper.front();
+ return m_oper.front();
}
void Channel::PopEnvelope()
{
- mOper.pop_front();
+ m_oper.pop_front();
}
-void Channel::SetLoop(bool loop) {
- mLoop = loop;
+void Channel::SetLoop(bool loop)
+{
+ m_loop = loop;
+}
+
+
+void Channel::Mute(bool mute)
+{
+ m_mute = mute;
}
+
+
+bool Channel::IsMuted()
+{
+ return m_mute;
+}
+
diff --git a/src/sound/oalsound/channel.h b/src/sound/oalsound/channel.h
index 8965306..a04b509 100644
--- a/src/sound/oalsound/channel.h
+++ b/src/sound/oalsound/channel.h
@@ -14,10 +14,18 @@
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/.
-// channel.h
+/**
+ * \file channel.h
+ * \brief OpenAL channel
+ */
#pragma once
+#include "sound/sound.h"
+
+#include "sound/oalsound/buffer.h"
+#include "sound/oalsound/check.h"
+
#include <string>
#include <deque>
#include <cassert>
@@ -25,11 +33,6 @@
#include <AL/al.h>
#include <AL/alc.h>
-#include "sound/sound.h"
-
-#include "buffer.h"
-#include "check.h"
-
struct SoundOper
{
float finalAmplitude;
@@ -42,62 +45,73 @@ struct SoundOper
class Channel
{
- public:
- Channel();
- ~Channel();
-
- bool Play();
- bool Stop();
- bool SetPosition(Math::Vector);
-
- bool SetFrequency(float);
- float GetFrequency();
- bool AdjustFrequency(float);
-
- float GetCurrentTime();
- void SetCurrentTime(float);
- float GetDuration();
-
- bool SetVolume(float);
- float GetVolume();
- bool IsPlaying();
- bool IsReady();
- bool IsLoaded();
-
- bool SetBuffer(Buffer *);
- bool FreeBuffer();
-
- bool HasEnvelope();
- SoundOper& GetEnvelope();
- void PopEnvelope();
-
- int GetPriority();
- void SetPriority(int);
-
- void SetStartAmplitude(float);
- void SetStartFrequency(float);
- void SetChangeFrequency(float);
-
- float GetStartAmplitude();
- float GetStartFrequency();
- float GetChangeFrequency();
- float GetInitFrequency();
-
- void AddOper(SoundOper);
- void ResetOper();
- Sound GetSoundType();
- void SetLoop(bool);
-
- private:
- Buffer *mBuffer;
- ALuint mSource;
-
- int mPriority;
- float mStartAmplitude;
- float mStartFrequency;
- float mChangeFrequency;
- float mInitFrequency;
- std::deque<SoundOper> mOper;
- bool mReady;
- bool mLoop;
+public:
+ Channel();
+ ~Channel();
+
+ bool Play();
+ bool Stop();
+
+ bool SetPan(Math::Vector);
+ void SetPosition(Math::Vector);
+ Math::Vector GetPosition();
+
+ bool SetFrequency(float);
+ float GetFrequency();
+
+ float GetCurrentTime();
+ void SetCurrentTime(float);
+ float GetDuration();
+
+ bool SetVolume(float);
+ float GetVolume();
+ void SetVolumeAtrib(float);
+ float GetVolumeAtrib();
+
+ bool IsPlaying();
+ bool IsReady();
+ bool IsLoaded();
+
+ bool SetBuffer(Buffer *);
+ bool FreeBuffer();
+
+ bool HasEnvelope();
+ SoundOper& GetEnvelope();
+ void PopEnvelope();
+
+ int GetPriority();
+ void SetPriority(int);
+
+ void SetStartAmplitude(float);
+ void SetStartFrequency(float);
+ void SetChangeFrequency(float);
+
+ float GetStartAmplitude();
+ float GetStartFrequency();
+ float GetChangeFrequency();
+ float GetInitFrequency();
+
+ void AddOper(SoundOper);
+ void ResetOper();
+ Sound GetSoundType();
+ void SetLoop(bool);
+ void Mute(bool);
+ bool IsMuted();
+
+private:
+ Buffer *m_buffer;
+ ALuint m_source;
+
+ int m_priority;
+ float m_startAmplitude;
+ float m_startFrequency;
+ float m_changeFrequency;
+ float m_initFrequency;
+ float m_volume;
+ std::deque<SoundOper> m_oper;
+ bool m_ready;
+ bool m_loop;
+ bool m_mute;
+ Math::Vector m_position;
};
+
diff --git a/src/sound/oalsound/check.h b/src/sound/oalsound/check.h
index cf3e468..f677e17 100644
--- a/src/sound/oalsound/check.h
+++ b/src/sound/oalsound/check.h
@@ -37,3 +37,4 @@ inline ALenum alGetCode()
CODE = AL_NO_ERROR;
return ret;
}
+
diff --git a/src/sound/sound.cpp b/src/sound/sound.cpp
new file mode 100644
index 0000000..d392612
--- /dev/null
+++ b/src/sound/sound.cpp
@@ -0,0 +1,191 @@
+// * This file is part of the COLOBOT source code
+// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
+// * Copyright (C) 2012-2013, Polish Portal of Colobot (PPC)
+// *
+// * This program is free software: you can redistribute it and/or modify
+// * it under the terms of the GNU General Public License as published by
+// * the Free Software Foundation, either version 3 of the License, or
+// * (at your option) any later version.
+// *
+// * This program is distributed in the hope that it will be useful,
+// * but WITHOUT ANY WARRANTY; without even the implied warranty of
+// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// * GNU General Public License for more details.
+// *
+// * You should have received a copy of the GNU General Public License
+// * along with this program. If not, see http://www.gnu.org/licenses/.
+
+#include "sound/sound.h"
+
+#include "math/vector.h"
+
+#include "common/logger.h"
+
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+
+#include <boost/filesystem.hpp>
+
+
+CSoundInterface::CSoundInterface()
+{
+}
+
+CSoundInterface::~CSoundInterface()
+{
+}
+
+bool CSoundInterface::Create(bool b3D)
+{
+ return true;
+}
+
+void CSoundInterface::CacheAll(std::string path)
+{
+ for ( int i = 1; i < SOUND_MAX; i++ )
+ {
+ std::stringstream filename;
+ filename << path << "/sound" << std::setfill('0') << std::setw(3) << i << ".wav";
+ if ( !Cache(static_cast<Sound>(i), filename.str()) )
+ GetLogger()->Warn("Unable to load audio: %s\n", filename.str().c_str());
+ }
+}
+
+void CSoundInterface::AddMusicFiles(std::string path)
+{
+ m_soundPath = path;
+ CacheMusic("Intro1.ogg");
+ CacheMusic("Intro2.ogg");
+ CacheMusic("music010.ogg");
+ CacheMusic("music011.ogg");
+}
+
+bool CSoundInterface::Cache(Sound bSound, std::string bFile)
+{
+ return true;
+}
+
+bool CSoundInterface::CacheMusic(std::string bFile)
+{
+ return true;
+}
+
+bool CSoundInterface::GetEnable()
+{
+ return true;
+}
+
+void CSoundInterface::SetSound3D(bool bMode)
+{
+}
+
+bool CSoundInterface::GetSound3D()
+{
+ return true;
+}
+
+bool CSoundInterface::GetSound3DCap()
+{
+ return true;
+}
+
+void CSoundInterface::SetAudioVolume(int volume)
+{
+}
+
+int CSoundInterface::GetAudioVolume()
+{
+ return 0;
+}
+
+void CSoundInterface::SetMusicVolume(int volume)
+{
+}
+
+int CSoundInterface::GetMusicVolume()
+{
+ return 0;
+}
+
+void CSoundInterface::SetListener(Math::Vector eye, Math::Vector lookat)
+{
+}
+
+void CSoundInterface::FrameMove(float rTime)
+{
+}
+
+int CSoundInterface::Play(Sound sound, float amplitude, float frequency, bool bLoop)
+{
+ return 0;
+}
+
+int CSoundInterface::Play(Sound sound, Math::Vector pos, float amplitude, float frequency, bool bLoop)
+{
+ return 0;
+}
+
+bool CSoundInterface::FlushEnvelope(int channel)
+{
+ return true;
+}
+
+bool CSoundInterface::AddEnvelope(int channel, float amplitude, float frequency, float time, SoundNext oper)
+{
+ return true;
+}
+
+bool CSoundInterface::Position(int channel, Math::Vector pos)
+{
+ return true;
+}
+
+bool CSoundInterface::Frequency(int channel, float frequency)
+{
+ return true;
+}
+
+bool CSoundInterface::Stop(int channel)
+{
+ return true;
+}
+
+bool CSoundInterface::StopAll()
+{
+ return true;
+}
+
+bool CSoundInterface::MuteAll(bool bMute)
+{
+ return true;
+}
+
+bool CSoundInterface::PlayMusic(int rank, bool bRepeat)
+{
+ return true;
+}
+
+bool CSoundInterface::PlayMusic(std::string filename, bool bRepeat)
+{
+ return true;
+}
+
+bool CSoundInterface::RestartMusic()
+{
+ return true;
+}
+
+void CSoundInterface::SuspendMusic()
+{
+}
+
+void CSoundInterface::StopMusic()
+{
+}
+
+bool CSoundInterface::IsPlayingMusic()
+{
+ return true;
+}
+
diff --git a/src/sound/sound.h b/src/sound/sound.h
index 70139ea..9ccc1b6 100644
--- a/src/sound/sound.h
+++ b/src/sound/sound.h
@@ -22,23 +22,16 @@
#pragma once
-#include <boost/filesystem.hpp>
-
#include "math/vector.h"
#include "common/logger.h"
#include <string>
-#include <iostream>
-#include <iomanip>
-#include <sstream>
-#include <map>
-
/*!
* Maximum possible audio volume
*/
-#define MAXVOLUME 100.0f
+const float MAXVOLUME = 100.0f;
/**
@@ -48,7 +41,7 @@
**/
enum Sound
{
- SOUND_NONE = -1,
+ SOUND_NONE = -1,
SOUND_CLICK = 0,
SOUND_BOUM = 1,
SOUND_EXPLO = 2,
@@ -130,7 +123,8 @@ enum Sound
SOUND_FIREp = 78, /*!< shooting with phazer */
SOUND_EXPLOg1 = 79, /*!< impact gun 1 */
SOUND_EXPLOg2 = 80, /*!< impact gun 2 */
- SOUND_MOTORd = 81, /*!< engine friction */
+// SOUND_MOTORd = 81, /*!< engine friction */
+ SOUND_MAX /** number of items in enum */
};
@@ -154,95 +148,88 @@ enum SoundNext
*/
class CSoundInterface
{
- public:
- inline CSoundInterface() {}
- inline virtual ~CSoundInterface() {}
+public:
+ CSoundInterface();
+ virtual ~CSoundInterface();
/** Function to initialize sound device
* \param b3D - enable support for 3D sound
*/
- inline virtual bool Create(bool b3D) { return true; };
+ virtual bool Create(bool b3D);
/** Function called to cache all sound effect files.
* Function calls \link CSoundInterface::Cache() \endlink for each file
*/
- inline void CacheAll(std::string path) {
- for ( int i = 1; i <= 81; i++ ) {
- std::stringstream filename;
- filename << path << "/sound" << std::setfill('0') << std::setw(3) << i << ".wav";
- if ( !Cache(static_cast<Sound>(i), filename.str()) )
- GetLogger()->Warn("Unable to load audio: %s\n", filename.str().c_str());
- }
- };
+ void CacheAll(std::string path);
/** Function called to add all music files to list */
- inline void AddMusicFiles(std::string path) {
- for ( int i = 1; i <= 12; i++ ) {
- std::stringstream filename;
- filename << path << "/music" << std::setfill('0') << std::setw(3) << i << ".ogg";
- if (boost::filesystem::exists(filename.str()))
- mMusic[i] = filename.str();
- }
- };
-
+ void AddMusicFiles(std::string path);
+
/** Function called to cache sound effect file.
* This function is called by plugin interface for each file.
* \param bSound - id of a file, will be used to identify sound files
* \param bFile - file to load
* \return return true on success
*/
- inline virtual bool Cache(Sound bSound, std::string bFile) { return true; };
+ virtual bool Cache(Sound bSound, std::string bFile);
+
+ /** Function called to cache music file.
+ * This function is called by CRobotMain for each file used in the mission.
+ * \param bFile - file to load
+ * \return return true on success
+ */
+ virtual bool CacheMusic(std::string bFile);
/** Return if plugin is enabled
* \return return true if plugin is enabled
*/
- inline virtual bool GetEnable() {return true;};
+ virtual bool GetEnable();
/** Change sound mode to 2D/3D
* \param bMode - true to enable 3D sound
*/
- inline virtual void SetSound3D(bool bMode) {};
+ virtual void SetSound3D(bool bMode);
/** Return if we use 3D sound
* \return true if we have 3D sound enabled
*/
- inline virtual bool GetSound3D() {return true;};
+ virtual bool GetSound3D();
/** Return if we have 3D sound capable card
* \return true for 3D sound support
*/
- inline virtual bool GetSound3DCap() {return true;};
+ virtual bool GetSound3DCap();
/** Change global sound volume
* \param volume - range from 0 to MAXVOLUME
*/
- inline virtual void SetAudioVolume(int volume) {};
+ virtual void SetAudioVolume(int volume);
/** Return global sound volume
* \return global volume as int in range from 0 to MAXVOLUME
*/
- inline virtual int GetAudioVolume() {return 0;};
+ virtual int GetAudioVolume();
/** Set music volume
* \param volume - range from 0 to MAXVOLUME
*/
- inline virtual void SetMusicVolume(int volume) {};
+ virtual void SetMusicVolume(int volume);
/** Return music volume
* \return music volume as int in range from 0 to MAXVOLUME
*/
- inline virtual int GetMusicVolume() {return 0;};
+ virtual int GetMusicVolume();
/** Set listener position
* \param eye - position of listener
* \param lookat - direction listener is looking at
*/
- inline virtual void SetListener(Math::Vector eye, Math::Vector lookat) {};
+ virtual void SetListener(Math::Vector eye, Math::Vector lookat);
/** Update data each frame
* \param rTime - time since last update
*/
- inline virtual void FrameMove(float rTime) {};
+ virtual void FrameMove(float rTime);
/** Play specific sound
* \param sound - sound to play
@@ -251,7 +238,7 @@ class CSoundInterface
* \param bLoop - loop sound
* \return identifier of channel that sound will be played on
*/
- inline virtual int Play(Sound sound, float amplitude=1.0f, float frequency=1.0f, bool bLoop = false) {return 0;};
+ virtual int Play(Sound sound, float amplitude=1.0f, float frequency=1.0f, bool bLoop = false);
/** Play specific sound
* \param sound - sound to play
@@ -261,13 +248,13 @@ class CSoundInterface
* \param bLoop - loop sound
* \return identifier of channel that sound will be played on
*/
- inline virtual int Play(Sound sound, Math::Vector pos, float amplitude=1.0f, float frequency=1.0f, bool bLoop = false) {return 0;};
+ virtual int Play(Sound sound, Math::Vector pos, float amplitude=1.0f, float frequency=1.0f, bool bLoop = false);
/** Remove all operations that would be made on sound in channel.
* \param channel - channel to work on
* \return return true on success
*/
- inline virtual bool FlushEnvelope(int channel) {return true;};
+ virtual bool FlushEnvelope(int channel);
/** Add envelope to sound. Envelope is a operatino that will be performend on sound in future like changing frequency
* \param channel - channel to work on
@@ -277,67 +264,74 @@ class CSoundInterface
* \param oper - operation to perform
* \return return true on success
*/
- inline virtual bool AddEnvelope(int channel, float amplitude, float frequency, float time, SoundNext oper) {return true;};
+ virtual bool AddEnvelope(int channel, float amplitude, float frequency, float time, SoundNext oper);
/** Set sound position in space
* \param channel - channel to work on
* \param pos - new positino of a sound
* \return return true on success
*/
- inline virtual bool Position(int channel, Math::Vector pos) {return true;};
+ virtual bool Position(int channel, Math::Vector pos);
/** Set sound frequency
* \param channel - channel to work on
* \param frequency - change sound frequency
* \return return true on success
*/
- inline virtual bool Frequency(int channel, float frequency) {return true;};
+ virtual bool Frequency(int channel, float frequency);
/** Stop playing sound
* \param channel - channel to work on
* \return return true on success
*/
- inline virtual bool Stop(int channel) {return true;};
+ virtual bool Stop(int channel);
/** Stop playing all sounds
* \return return true on success
*/
- inline virtual bool StopAll() {return true;};
+ virtual bool StopAll();
/** Mute/unmute all sounds
* \param bMute
* \return return true on success
*/
- inline virtual bool MuteAll(bool bMute) {return true;};
+ virtual bool MuteAll(bool bMute);
/** Start playing music
* \param rank - track number
* \param bRepeat - repeat playing
* \return return true on success
*/
- inline virtual bool PlayMusic(int rank, bool bRepeat) {return true;};
+ virtual bool PlayMusic(int rank, bool bRepeat);
+
+ /** Start playing music
+ * \param filename - name of file to play
+ * \param bRepeat - repeat playing
+ * \return return true on success
+ */
+ virtual bool PlayMusic(std::string filename, bool bRepeat);
/** Restart music
* @return return true on success
*/
- inline virtual bool RestartMusic() {return true;};
+ virtual bool RestartMusic();
/** Susspend paying music
* \return return true on success
*/
- inline virtual void SuspendMusic() {};
+ virtual void SuspendMusic();
/** Stop playing music
* \return return true on success
*/
- inline virtual void StopMusic() {};
+ virtual void StopMusic();
/** Check if music if playing
* \return return true if music is playing
*/
- inline virtual bool IsPlayingMusic() {return true;};
+ virtual bool IsPlayingMusic();
- protected:
- std::map<int, std::string> mMusic;
+protected:
+ std::string m_soundPath;
};