Refactored sound code

* fixed formatting and naming to be uniform with rest of code
 * moved default implementation of CSound to cpp module
dev-ui
Piotr Dziwinski 2013-05-26 19:34:05 +02:00
parent 8765d58b02
commit 950a3474d5
16 changed files with 822 additions and 500 deletions

View File

@ -155,6 +155,7 @@ physics/physics.cpp
script/cbottoken.cpp
script/cmdtoken.cpp
script/script.cpp
sound/sound.cpp
ui/button.cpp
ui/check.cpp
ui/color.cpp

View File

@ -25,8 +25,8 @@ template<> CLogger* CSingleton<CLogger>::m_instance = nullptr;
CLogger::CLogger()
{
mFile = NULL;
mLogLevel = LOG_INFO;
m_file = NULL;
m_logLevel = LOG_INFO;
}
@ -38,31 +38,31 @@ CLogger::~CLogger()
void CLogger::Log(LogLevel type, const char* str, va_list args)
{
if (type < mLogLevel)
if (type < m_logLevel)
return;
switch (type)
{
case LOG_TRACE:
fprintf(IsOpened() ? mFile : stderr, "[TRACE]: ");
fprintf(IsOpened() ? m_file : stderr, "[TRACE]: ");
break;
case LOG_DEBUG:
fprintf(IsOpened() ? mFile : stderr, "[DEBUG]: ");
fprintf(IsOpened() ? m_file : stderr, "[DEBUG]: ");
break;
case LOG_WARN:
fprintf(IsOpened() ? mFile : stderr, "[WARN]: ");
fprintf(IsOpened() ? m_file : stderr, "[WARN]: ");
break;
case LOG_INFO:
fprintf(IsOpened() ? mFile : stderr, "[INFO]: ");
fprintf(IsOpened() ? m_file : stderr, "[INFO]: ");
break;
case LOG_ERROR:
fprintf(IsOpened() ? mFile : stderr, "[ERROR]: ");
fprintf(IsOpened() ? m_file : stderr, "[ERROR]: ");
break;
default:
break;
}
vfprintf(IsOpened() ? mFile : stderr, str, args);
vfprintf(IsOpened() ? m_file : stderr, str, args);
}
@ -122,36 +122,36 @@ void CLogger::Message(const char* str, ...)
void CLogger::SetOutputFile(std::string filename)
{
mFilename = filename;
m_filename = filename;
Open();
}
void CLogger::Open()
{
mFile = fopen(mFilename.c_str(), "w");
m_file = fopen(m_filename.c_str(), "w");
if (mFile == NULL)
fprintf(stderr, "Could not create file %s\n", mFilename.c_str());
if (m_file == NULL)
fprintf(stderr, "Could not create file %s\n", m_filename.c_str());
}
void CLogger::Close()
{
if (IsOpened())
fclose(mFile);
fclose(m_file);
}
bool CLogger::IsOpened()
{
return mFile != NULL;
return m_file != NULL;
}
void CLogger::SetLogLevel(LogLevel type)
{
mLogLevel = type;
m_logLevel = type;
}

View File

@ -113,9 +113,9 @@ public:
static bool ParseLogLevel(const std::string& str, LogLevel& logLevel);
private:
std::string mFilename;
FILE *mFile;
LogLevel mLogLevel;
std::string m_filename;
FILE *m_file;
LogLevel m_logLevel;
void Open();
void Close();

View File

@ -42,6 +42,8 @@
#include "ui/interface.h"
#include <iomanip>
template<> Gfx::CEngine* CSingleton<Gfx::CEngine>::m_instance = nullptr;
// Graphics module namespace

View File

@ -79,6 +79,7 @@
#include "ui/slider.h"
#include "ui/window.h"
#include <iomanip>
template<> CRobotMain* CSingleton<CRobotMain>::m_instance = nullptr;

View File

@ -2,3 +2,4 @@
* \dir src/sound
* \brief Sound module - playing sounds and music
*/

View File

@ -16,19 +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;
mCurrentMusic = nullptr;
mEye.LoadZero();
mLookat.LoadZero();
m_enabled = false;
m_3D = false;
m_audioVolume = 1.0f;
m_musicVolume = 1.0f;
m_currentMusic = nullptr;
m_eye.LoadZero();
m_lookat.LoadZero();
}
@ -40,31 +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;
}
if (mCurrentMusic) {
delete mCurrentMusic;
if (m_currentMusic)
{
delete m_currentMusic;
}
for (auto item : mSounds) {
for (auto item : m_sounds)
{
delete item.second;
}
for (auto item : mMusic) {
for (auto item : m_music)
{
delete item.second;
}
mEnabled = false;
m_enabled = false;
alcDestroyContext(mContext);
alcCloseDevice(mDevice);
alcDestroyContext(m_context);
alcCloseDevice(m_device);
}
}
@ -73,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);
alListenerf(AL_GAIN, mAudioVolume);
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)
{
m3D = bMode;
m_3D = bMode;
}
bool ALSound::GetSound3D()
{
return m3D;
return m_3D;
}
@ -120,48 +130,50 @@ bool ALSound::GetSound3DCap()
bool ALSound::GetEnable()
{
return mEnabled;
return m_enabled;
}
void ALSound::SetAudioVolume(int volume)
{
mAudioVolume = static_cast<float>(volume) / MAXVOLUME;
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 = static_cast<float>(volume) / MAXVOLUME;
if (mCurrentMusic) {
mCurrentMusic->SetVolume(mMusicVolume);
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;
@ -169,12 +181,14 @@ bool ALSound::Cache(Sound sound, std::string filename)
bool ALSound::CacheMusic(std::string filename)
{
if(mMusic.find(filename) == mMusic.end()) {
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))) {
mMusic[filename] = buffer;
if (buffer->LoadFromFile(file.str(), static_cast<Sound>(-1)))
{
m_music[filename] = buffer;
return true;
}
}
@ -235,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)
@ -248,12 +263,14 @@ 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;
@ -264,17 +281,21 @@ bool ALSound::SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded)
}
// 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;
@ -286,8 +307,10 @@ bool ALSound::SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded)
}
int lowerOrEqual = -1;
for (auto it : mChannels) {
if (it.second->GetPriority() < priority) {
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;
@ -296,7 +319,8 @@ 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.\n");
return true;
@ -309,16 +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, mEye, 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;
}
@ -328,29 +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 (!m3D) {
if (!m_3D)
{
ComputeVolumePan2D(channel, pos);
} else {
mChannels[channel]->SetVolumeAtrib(1.0f);
}
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(powf(amplitude * mChannels[channel]->GetVolumeAtrib(), 0.2f) * 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;
}
@ -358,21 +389,23 @@ 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;
}
@ -382,7 +415,7 @@ bool ALSound::AddEnvelope(int channel, float amplitude, float frequency, float t
op.totalTime = time;
op.nextOper = oper;
op.currentTime = 0.0f;
mChannels[channel]->AddOper(op);
m_channels[channel]->AddOper(op);
return true;
}
@ -390,21 +423,26 @@ 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;
}
if (m3D) {
mChannels[channel]->SetPan(pos);
} else {
if (m_3D)
{
m_channels[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);
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;
@ -413,29 +451,31 @@ bool ALSound::Position(int channel, Math::Vector pos)
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;
}
@ -443,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();
}
@ -457,19 +498,24 @@ bool ALSound::StopAll()
bool ALSound::MuteAll(bool bMute)
{
if (!mEnabled)
if (!m_enabled)
return false;
for (auto it : mChannels) {
if (it.second->IsPlaying()) {
for (auto it : m_channels)
{
if (it.second->IsPlaying())
{
it.second->Mute(bMute);
}
}
if (bMute) {
mCurrentMusic->SetVolume(0.0f);
} else {
mCurrentMusic->SetVolume(mMusicVolume);
if (bMute)
{
m_currentMusic->SetVolume(0.0f);
}
else
{
m_currentMusic->SetVolume(m_musicVolume);
}
return true;
}
@ -477,17 +523,20 @@ bool ALSound::MuteAll(bool bMute)
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()) {
if (it.second->IsMuted())
{
it.second->SetVolume(0.0f);
continue;
}
@ -498,12 +547,12 @@ 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();
it.second->SetVolume(powf(volume * it.second->GetVolumeAtrib(), 0.2f) * mAudioVolume);
it.second->SetVolume(powf(volume * it.second->GetVolumeAtrib(), 0.2f) * m_audioVolume);
// setting frequency
frequency = progress;
@ -513,14 +562,19 @@ void ALSound::FrameMove(float delta)
frequency = (frequency * it.second->GetInitFrequency());
it.second->SetFrequency(frequency);
if (oper.totalTime <= oper.currentTime) {
if (oper.nextOper == SOPER_LOOP) {
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();
}
@ -533,26 +587,32 @@ void ALSound::FrameMove(float delta)
void ALSound::SetListener(Math::Vector eye, Math::Vector lookat)
{
mEye = eye;
mLookat = lookat;
if (m3D) {
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 {
}
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 : mChannels) {
if (it.second->IsPlaying()) {
for (auto it : m_channels)
{
if (it.second->IsPlaying())
{
Math::Vector pos = it.second->GetPosition();
ComputeVolumePan2D(it.first, pos);
if (!it.second->HasEnvelope()) {
if (!it.second->HasEnvelope())
{
float volume = it.second->GetStartAmplitude();
it.second->SetVolume(powf(volume * it.second->GetVolumeAtrib(), 0.2f) * mAudioVolume);
it.second->SetVolume(powf(volume * it.second->GetVolumeAtrib(), 0.2f) * m_audioVolume);
}
}
}
@ -568,7 +628,8 @@ bool ALSound::PlayMusic(int rank, bool bRepeat)
bool ALSound::PlayMusic(std::string filename, bool bRepeat)
{
if (!mEnabled) {
if (!m_enabled)
{
return false;
}
@ -576,23 +637,27 @@ bool ALSound::PlayMusic(std::string filename, bool bRepeat)
file << m_soundPath << "/" << filename;
// check if we have music in cache
if (mMusic.find(filename) == mMusic.end()) {
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())) {
if (!boost::filesystem::exists(file.str()))
{
GetLogger()->Warn("Requested music %s was not found.\n", filename.c_str());
return false;
}
Buffer *buffer = new Buffer();
buffer->LoadFromFile(file.str(), static_cast<Sound>(-1));
mCurrentMusic->SetBuffer(buffer);
} else {
m_currentMusic->SetBuffer(buffer);
}
else
{
GetLogger()->Debug("Music loaded from cache\n");
mCurrentMusic->SetBuffer(mMusic[filename]);
m_currentMusic->SetBuffer(m_music[filename]);
}
mCurrentMusic->SetVolume(mMusicVolume);
mCurrentMusic->SetLoop(bRepeat);
mCurrentMusic->Play();
m_currentMusic->SetVolume(m_musicVolume);
m_currentMusic->SetLoop(bRepeat);
m_currentMusic->Play();
return true;
}
@ -600,18 +665,20 @@ bool ALSound::PlayMusic(std::string filename, bool bRepeat)
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;
}
@ -621,70 +688,84 @@ void ALSound::StopMusic()
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;
}
mCurrentMusic->Stop();
m_currentMusic->Stop();
}
void ALSound::ComputeVolumePan2D(int channel, Math::Vector &pos)
{
float dist, a, g;
mChannels[channel]->SetPosition(pos);
m_channels[channel]->SetPosition(pos);
if (VectorsEqual(pos, mEye)) {
mChannels[channel]->SetVolumeAtrib(1.0f); // maximum volume
mChannels[channel]->SetPan(Math::Vector()); // at the center
if (VectorsEqual(pos, m_eye))
{
m_channels[channel]->SetVolumeAtrib(1.0f); // maximum volume
m_channels[channel]->SetPan(Math::Vector()); // at the center
return;
}
dist = Distance(pos, mEye);
if ( dist >= 110.0f ) { // very far?
mChannels[channel]->SetVolumeAtrib(0.0f); // silence
mChannels[channel]->SetPan(Math::Vector()); // at the center
return;
} else if ( dist <= 10.0f ) { // very close?
mChannels[channel]->SetVolumeAtrib(1.0f); // maximum volume
mChannels[channel]->SetPan(Math::Vector()); // at the center
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;
}
mChannels[channel]->SetVolumeAtrib(1.0f - ((dist - 10.0f) / 100.0f));
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(mLookat.x - mEye.x, mLookat.z - mEye.z, 0.0f), one);
float angle_g = Angle(Math::Vector(pos.x - mEye.x, pos.z - mEye.z, 0.0f), one);
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 ) {
if ( a < 0.0f )
{
a += Math::PI * 2.0f;
}
if ( g < 0.0f ) {
if ( g < 0.0f )
{
g += Math::PI * 2.0f;
}
if ( a < g ) {
if (a + Math::PI * 2.0f - g < g - a ) {
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 ) {
}
else
{
if ( g + Math::PI * 2.0f - a < a - g )
{
g += Math::PI * 2.0f;
}
}
mChannels[channel]->SetPan( Math::Vector(0.0f, 0.0f, sinf(g - a)) );
m_channels[channel]->SetPan( Math::Vector(0.0f, 0.0f, sinf(g - a)) );
}

View File

@ -15,86 +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();
public:
ALSound();
~ALSound();
bool Create(bool b3D);
bool Cache(Sound, std::string);
bool CacheMusic(std::string);
bool Create(bool b3D);
bool Cache(Sound, std::string);
bool CacheMusic(std::string);
bool GetEnable();
bool GetEnable();
void SetSound3D(bool bMode);
bool GetSound3D();
bool GetSound3DCap();
void SetSound3D(bool bMode);
bool GetSound3D();
bool GetSound3DCap();
void SetAudioVolume(int volume);
int GetAudioVolume();
void SetMusicVolume(int volume);
int GetMusicVolume();
void SetAudioVolume(int volume);
int GetAudioVolume();
void SetMusicVolume(int volume);
int GetMusicVolume();
void SetListener(Math::Vector eye, Math::Vector lookat);
void FrameMove(float rTime);
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);
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();
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 &);
// 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);
private:
void CleanUp();
int GetPriority(Sound);
bool SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded);
void ComputeVolumePan2D(int channel, Math::Vector &pos);
bool mEnabled;
bool m3D;
float mAudioVolume;
float mMusicVolume;
ALCdevice* mDevice;
ALCcontext* mContext;
std::map<Sound, Buffer*> mSounds;
std::map<std::string, Buffer*> mMusic;
std::map<int, Channel*> mChannels;
Channel *mCurrentMusic;
Math::Vector mEye;
Math::Vector mLookat;
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;
};

View File

@ -15,25 +15,29 @@
// * 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;
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;
@ -45,16 +49,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 +70,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);
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;
}

View File

@ -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();
public:
Buffer();
~Buffer();
bool LoadFromFile(std::string, Sound);
bool IsLoaded();
bool LoadFromFile(std::string, Sound);
bool IsLoaded();
Sound GetSoundType();
ALuint GetBuffer();
float GetDuration();
Sound GetSoundType();
ALuint GetBuffer();
float GetDuration();
private:
ALuint mBuffer;
Sound mSound;
bool mLoaded;
float mDuration;
private:
ALuint m_buffer;
Sound m_sound;
bool m_loaded;
float m_duration;
};

View File

@ -15,37 +15,41 @@
// * along with this program. If not, see http://www.gnu.org/licenses/.
#include "channel.h"
#include "sound/oalsound/channel.h"
Channel::Channel()
{
alGenSources(1, &mSource);
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;
}
else
{
m_ready = true;
}
mPriority = 0;
mBuffer = nullptr;
mLoop = false;
mMute = false;
mInitFrequency = 0.0f;
mStartAmplitude = 0.0f;
mStartFrequency = 0.0f;
mChangeFrequency = 0.0f;
mVolume = 0.0f;
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 (mReady) {
alSourceStop(mSource);
alSourcei(mSource, AL_BUFFER, 0);
alDeleteSources(1, &mSource);
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());
}
@ -54,15 +58,17 @@ Channel::~Channel()
bool Channel::Play()
{
if (!mReady || mBuffer == nullptr) {
if (!m_ready || m_buffer == nullptr)
{
return false;
}
alSourcei(mSource, AL_LOOPING, static_cast<ALint>(mLoop));
alSourcei(mSource, AL_REFERENCE_DISTANCE, 10.0f);
alSourcei(mSource, AL_MAX_DISTANCE, 110.0f);
alSourcePlay(mSource);
if (alCheck()) {
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;
@ -71,12 +77,14 @@ bool Channel::Play()
bool Channel::SetPan(Math::Vector pos)
{
if (!mReady || mBuffer == nullptr) {
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;
}
@ -86,24 +94,26 @@ bool Channel::SetPan(Math::Vector pos)
void Channel::SetPosition(Math::Vector pos)
{
mPosition = pos;
m_position = pos;
}
Math::Vector Channel::GetPosition()
{
return mPosition;
return m_position;
}
bool Channel::SetFrequency(float freq)
{
if (!mReady || mBuffer == nullptr) {
if (!m_ready || m_buffer == nullptr)
{
return false;
}
alSourcef(mSource, AL_PITCH, freq);
if (alCheck()) {
alSourcef(m_source, AL_PITCH, freq);
if (alCheck())
{
GetLogger()->Warn("Could not set sound pitch to '%f'. Code: %d\n", freq, alGetCode());
return false;
}
@ -114,12 +124,14 @@ bool Channel::SetFrequency(float freq)
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;
}
@ -130,12 +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, vol);
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;
}
@ -146,12 +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;
}
@ -162,134 +178,144 @@ float Channel::GetVolume()
void Channel::SetVolumeAtrib(float volume)
{
mVolume = volume;
m_volume = volume;
}
float Channel::GetVolumeAtrib()
{
return mVolume;
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;
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);
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 || !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;
}
@ -298,22 +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;
}
@ -323,13 +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;
}
@ -339,12 +372,14 @@ 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);
if (alCheck()) {
alSourcef(m_source, AL_SEC_OFFSET, current);
if (alCheck())
{
GetLogger()->Warn("Could not get source current play time. Code: %d\n", alGetCode());
}
}
@ -352,44 +387,47 @@ void Channel::SetCurrentTime(float current)
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)
{
mMute = mute;
m_mute = mute;
}
bool Channel::IsMuted()
{
return mMute;
return m_mute;
}

View File

@ -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,72 +45,73 @@ struct SoundOper
class Channel
{
public:
Channel();
~Channel();
public:
Channel();
~Channel();
bool Play();
bool Stop();
bool Play();
bool Stop();
bool SetPan(Math::Vector);
void SetPosition(Math::Vector);
Math::Vector GetPosition();
bool SetPan(Math::Vector);
void SetPosition(Math::Vector);
Math::Vector GetPosition();
bool SetFrequency(float);
float GetFrequency();
bool SetFrequency(float);
float GetFrequency();
float GetCurrentTime();
void SetCurrentTime(float);
float GetDuration();
float GetCurrentTime();
void SetCurrentTime(float);
float GetDuration();
bool SetVolume(float);
float GetVolume();
void SetVolumeAtrib(float);
float GetVolumeAtrib();
bool SetVolume(float);
float GetVolume();
void SetVolumeAtrib(float);
float GetVolumeAtrib();
bool IsPlaying();
bool IsReady();
bool IsLoaded();
bool IsPlaying();
bool IsReady();
bool IsLoaded();
bool SetBuffer(Buffer *);
bool FreeBuffer();
bool SetBuffer(Buffer *);
bool FreeBuffer();
bool HasEnvelope();
SoundOper& GetEnvelope();
void PopEnvelope();
bool HasEnvelope();
SoundOper& GetEnvelope();
void PopEnvelope();
int GetPriority();
void SetPriority(int);
int GetPriority();
void SetPriority(int);
void SetStartAmplitude(float);
void SetStartFrequency(float);
void SetChangeFrequency(float);
void SetStartAmplitude(float);
void SetStartFrequency(float);
void SetChangeFrequency(float);
float GetStartAmplitude();
float GetStartFrequency();
float GetChangeFrequency();
float GetInitFrequency();
float GetStartAmplitude();
float GetStartFrequency();
float GetChangeFrequency();
float GetInitFrequency();
void AddOper(SoundOper);
void ResetOper();
Sound GetSoundType();
void SetLoop(bool);
void Mute(bool);
bool IsMuted();
void AddOper(SoundOper);
void ResetOper();
Sound GetSoundType();
void SetLoop(bool);
void Mute(bool);
bool IsMuted();
private:
Buffer *mBuffer;
ALuint mSource;
private:
Buffer *m_buffer;
ALuint m_source;
int mPriority;
float mStartAmplitude;
float mStartFrequency;
float mChangeFrequency;
float mInitFrequency;
float mVolume;
std::deque<SoundOper> mOper;
bool mReady;
bool mLoop;
bool mMute;
Math::Vector mPosition;
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;
};

View File

@ -37,3 +37,4 @@ inline ALenum alGetCode()
CODE = AL_NO_ERROR;
return ret;
}

191
src/sound/sound.cpp Normal file
View File

@ -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;
}

View File

@ -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;
/**
@ -131,6 +124,7 @@ enum Sound
SOUND_EXPLOg1 = 79, /*!< impact gun 1 */
SOUND_EXPLOg2 = 80, /*!< impact gun 2 */
// SOUND_MOTORd = 81, /*!< engine friction */
SOUND_MAX /** number of items in enum */
};
@ -154,35 +148,22 @@ 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 <= 80; 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) {
m_soundPath = path;
CacheMusic("Intro1.ogg");
CacheMusic("Intro2.ogg");
CacheMusic("music010.ogg");
CacheMusic("music011.ogg");
};
void AddMusicFiles(std::string path);
/** Function called to cache sound effect file.
* This function is called by plugin interface for each file.
@ -190,65 +171,65 @@ class CSoundInterface
* \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
*/
inline virtual bool CacheMusic(std::string bFile) { return true; };
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
@ -257,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
@ -267,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
@ -283,74 +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
*/
inline virtual bool PlayMusic(std::string filename, bool bRepeat) {return true;};
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::string m_soundPath;
protected:
std::string m_soundPath;
};

View File

@ -118,6 +118,7 @@ ${SRC_DIR}/physics/physics.cpp
${SRC_DIR}/script/cbottoken.cpp
${SRC_DIR}/script/cmdtoken.cpp
${SRC_DIR}/script/script.cpp
${SRC_DIR}/sound/sound.cpp
${SRC_DIR}/ui/button.cpp
${SRC_DIR}/ui/check.cpp
${SRC_DIR}/ui/color.cpp