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/cbottoken.cpp
script/cmdtoken.cpp script/cmdtoken.cpp
script/script.cpp script/script.cpp
sound/sound.cpp
ui/button.cpp ui/button.cpp
ui/check.cpp ui/check.cpp
ui/color.cpp ui/color.cpp

View File

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

View File

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

View File

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

View File

@ -2,3 +2,4 @@
* \dir src/sound * \dir src/sound
* \brief Sound module - playing sounds and music * \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/. // * 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() ALSound::ALSound()
{ {
mEnabled = false; m_enabled = false;
m3D = false; m_3D = false;
mAudioVolume = 1.0f; m_audioVolume = 1.0f;
mMusicVolume = 1.0f; m_musicVolume = 1.0f;
mCurrentMusic = nullptr; m_currentMusic = nullptr;
mEye.LoadZero(); m_eye.LoadZero();
mLookat.LoadZero(); m_lookat.LoadZero();
} }
@ -40,31 +43,36 @@ ALSound::~ALSound()
void ALSound::CleanUp() void ALSound::CleanUp()
{ {
if (mEnabled) { if (m_enabled)
{
GetLogger()->Info("Unloading files and closing device...\n"); GetLogger()->Info("Unloading files and closing device...\n");
StopAll(); StopAll();
StopMusic(); StopMusic();
for (auto channel : mChannels) { for (auto channel : m_channels)
{
delete channel.second; delete channel.second;
} }
if (mCurrentMusic) { if (m_currentMusic)
delete mCurrentMusic; {
delete m_currentMusic;
} }
for (auto item : mSounds) { for (auto item : m_sounds)
{
delete item.second; delete item.second;
} }
for (auto item : mMusic) { for (auto item : m_music)
{
delete item.second; delete item.second;
} }
mEnabled = false; m_enabled = false;
alcDestroyContext(mContext); alcDestroyContext(m_context);
alcCloseDevice(mDevice); alcCloseDevice(m_device);
} }
} }
@ -73,41 +81,43 @@ bool ALSound::Create(bool b3D)
{ {
CleanUp(); CleanUp();
if (mEnabled) if (m_enabled)
return true; return true;
GetLogger()->Info("Opening audio device...\n"); GetLogger()->Info("Opening audio device...\n");
mDevice = alcOpenDevice(NULL); m_device = alcOpenDevice(NULL);
if (!mDevice) { if (!m_device)
{
GetLogger()->Error("Could not open audio device!\n"); GetLogger()->Error("Could not open audio device!\n");
return false; return false;
} }
mContext = alcCreateContext(mDevice, NULL); m_context = alcCreateContext(m_device, NULL);
if (!mContext) { if (!m_context)
{
GetLogger()->Error("Could not create audio context!\n"); GetLogger()->Error("Could not create audio context!\n");
return false; return false;
} }
alcMakeContextCurrent(mContext); alcMakeContextCurrent(m_context);
alListenerf(AL_GAIN, mAudioVolume); alListenerf(AL_GAIN, m_audioVolume);
alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED); alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
mCurrentMusic = new Channel(); m_currentMusic = new Channel();
GetLogger()->Info("Done.\n"); GetLogger()->Info("Done.\n");
mEnabled = true; m_enabled = true;
return true; return true;
} }
void ALSound::SetSound3D(bool bMode) void ALSound::SetSound3D(bool bMode)
{ {
m3D = bMode; m_3D = bMode;
} }
bool ALSound::GetSound3D() bool ALSound::GetSound3D()
{ {
return m3D; return m_3D;
} }
@ -120,48 +130,50 @@ bool ALSound::GetSound3DCap()
bool ALSound::GetEnable() bool ALSound::GetEnable()
{ {
return mEnabled; return m_enabled;
} }
void ALSound::SetAudioVolume(int volume) void ALSound::SetAudioVolume(int volume)
{ {
mAudioVolume = static_cast<float>(volume) / MAXVOLUME; m_audioVolume = static_cast<float>(volume) / MAXVOLUME;
} }
int ALSound::GetAudioVolume() int ALSound::GetAudioVolume()
{ {
if ( !mEnabled ) if ( !m_enabled )
return 0; return 0;
return mAudioVolume * MAXVOLUME; return m_audioVolume * MAXVOLUME;
} }
void ALSound::SetMusicVolume(int volume) void ALSound::SetMusicVolume(int volume)
{ {
mMusicVolume = static_cast<float>(volume) / MAXVOLUME; m_musicVolume = static_cast<float>(volume) / MAXVOLUME;
if (mCurrentMusic) { if (m_currentMusic)
mCurrentMusic->SetVolume(mMusicVolume); {
m_currentMusic->SetVolume(m_musicVolume);
} }
} }
int ALSound::GetMusicVolume() int ALSound::GetMusicVolume()
{ {
if ( !mEnabled ) if ( !m_enabled )
return 0.0f; return 0.0f;
return mMusicVolume * MAXVOLUME; return m_musicVolume * MAXVOLUME;
} }
bool ALSound::Cache(Sound sound, std::string filename) bool ALSound::Cache(Sound sound, std::string filename)
{ {
Buffer *buffer = new Buffer(); Buffer *buffer = new Buffer();
if (buffer->LoadFromFile(filename, sound)) { if (buffer->LoadFromFile(filename, sound))
mSounds[sound] = buffer; {
m_sounds[sound] = buffer;
return true; return true;
} }
return false; return false;
@ -169,12 +181,14 @@ bool ALSound::Cache(Sound sound, std::string filename)
bool ALSound::CacheMusic(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(); Buffer *buffer = new Buffer();
std::stringstream file; std::stringstream file;
file << m_soundPath << "/" << filename; file << m_soundPath << "/" << filename;
if (buffer->LoadFromFile(file.str(), static_cast<Sound>(-1))) { if (buffer->LoadFromFile(file.str(), static_cast<Sound>(-1)))
mMusic[filename] = buffer; {
m_music[filename] = buffer;
return true; return true;
} }
} }
@ -235,7 +249,8 @@ bool ALSound::SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded)
int priority = GetPriority(sound); int priority = GetPriority(sound);
// Seeks a channel used which sound is stopped. // Seeks a channel used which sound is stopped.
for (auto it : mChannels) { for (auto it : m_channels)
{
if (it.second->IsPlaying()) if (it.second->IsPlaying())
continue; continue;
if (it.second->GetSoundType() != sound) 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 // just add a new channel if we dont have any
if (mChannels.size() == 0) { if (m_channels.size() == 0)
{
Channel *chn = new Channel(); Channel *chn = new Channel();
// check if we channel ready to play music, if not report error // check if we channel ready to play music, if not report error
if (chn->IsReady()) { if (chn->IsReady())
{
chn->SetPriority(priority); chn->SetPriority(priority);
mChannels[1] = chn; m_channels[1] = chn;
channel = 1; channel = 1;
bAlreadyLoaded = false; bAlreadyLoaded = false;
return true; return true;
@ -264,17 +281,21 @@ bool ALSound::SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded)
} }
// Seeks a channel completely free. // Seeks a channel completely free.
if (mChannels.size() < 64) { if (m_channels.size() < 64)
auto it = mChannels.end(); {
auto it = m_channels.end();
it--; it--;
int i = (*it).first; int i = (*it).first;
while (++i) { while (++i)
if (mChannels.find(i) == mChannels.end()) { {
if (m_channels.find(i) == m_channels.end())
{
Channel *chn = new Channel(); Channel *chn = new Channel();
// check if channel is ready to play music, if not destroy it and seek free one // 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); chn->SetPriority(priority);
mChannels[++i] = chn; m_channels[++i] = chn;
channel = i; channel = i;
bAlreadyLoaded = false; bAlreadyLoaded = false;
return true; return true;
@ -286,8 +307,10 @@ bool ALSound::SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded)
} }
int lowerOrEqual = -1; int lowerOrEqual = -1;
for (auto it : mChannels) { for (auto it : m_channels)
if (it.second->GetPriority() < priority) { {
if (it.second->GetPriority() < priority)
{
GetLogger()->Debug("Sound channel with lower priority will be reused.\n"); GetLogger()->Debug("Sound channel with lower priority will be reused.\n");
channel = it.first; channel = it.first;
return true; return true;
@ -296,7 +319,8 @@ bool ALSound::SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded)
lowerOrEqual = it.first; lowerOrEqual = it.first;
} }
if (lowerOrEqual != -1) { if (lowerOrEqual != -1)
{
channel = lowerOrEqual; channel = lowerOrEqual;
GetLogger()->Debug("Sound channel with lower or equal priority will be reused.\n"); GetLogger()->Debug("Sound channel with lower or equal priority will be reused.\n");
return true; 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) 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) int ALSound::Play(Sound sound, Math::Vector pos, float amplitude, float frequency, bool bLoop)
{ {
if (!mEnabled) { if (!m_enabled)
{
return -1; 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); GetLogger()->Warn("Sound %d was not loaded!\n", sound);
return -1; return -1;
} }
@ -328,29 +354,34 @@ int ALSound::Play(Sound sound, Math::Vector pos, float amplitude, float frequenc
if (!SearchFreeBuffer(sound, channel, bAlreadyLoaded)) if (!SearchFreeBuffer(sound, channel, bAlreadyLoaded))
return -1; return -1;
if (!bAlreadyLoaded) { if (!bAlreadyLoaded)
if (!mChannels[channel]->SetBuffer(mSounds[sound])) { {
mChannels[channel]->SetBuffer(nullptr); if (!m_channels[channel]->SetBuffer(m_sounds[sound]))
{
m_channels[channel]->SetBuffer(nullptr);
return -1; return -1;
} }
} }
Position(channel, pos); Position(channel, pos);
if (!m3D) { if (!m_3D)
{
ComputeVolumePan2D(channel, pos); ComputeVolumePan2D(channel, pos);
} else { }
mChannels[channel]->SetVolumeAtrib(1.0f); else
{
m_channels[channel]->SetVolumeAtrib(1.0f);
} }
// setting initial values // setting initial values
mChannels[channel]->SetStartAmplitude(amplitude); m_channels[channel]->SetStartAmplitude(amplitude);
mChannels[channel]->SetStartFrequency(frequency); m_channels[channel]->SetStartFrequency(frequency);
mChannels[channel]->SetChangeFrequency(1.0f); m_channels[channel]->SetChangeFrequency(1.0f);
mChannels[channel]->ResetOper(); m_channels[channel]->ResetOper();
mChannels[channel]->SetFrequency(frequency); m_channels[channel]->SetFrequency(frequency);
mChannels[channel]->SetVolume(powf(amplitude * mChannels[channel]->GetVolumeAtrib(), 0.2f) * mAudioVolume); m_channels[channel]->SetVolume(powf(amplitude * m_channels[channel]->GetVolumeAtrib(), 0.2f) * m_audioVolume);
mChannels[channel]->SetLoop(bLoop); m_channels[channel]->SetLoop(bLoop);
mChannels[channel]->Play(); m_channels[channel]->Play();
return channel; return channel;
} }
@ -358,21 +389,23 @@ int ALSound::Play(Sound sound, Math::Vector pos, float amplitude, float frequenc
bool ALSound::FlushEnvelope(int channel) bool ALSound::FlushEnvelope(int channel)
{ {
if (mChannels.find(channel) == mChannels.end()) { if (m_channels.find(channel) == m_channels.end())
{
return false; return false;
} }
mChannels[channel]->ResetOper(); m_channels[channel]->ResetOper();
return true; return true;
} }
bool ALSound::AddEnvelope(int channel, float amplitude, float frequency, float time, SoundNext oper) bool ALSound::AddEnvelope(int channel, float amplitude, float frequency, float time, SoundNext oper)
{ {
if (!mEnabled) if (!m_enabled)
return false; return false;
if (mChannels.find(channel) == mChannels.end()) { if (m_channels.find(channel) == m_channels.end())
{
return false; return false;
} }
@ -382,7 +415,7 @@ bool ALSound::AddEnvelope(int channel, float amplitude, float frequency, float t
op.totalTime = time; op.totalTime = time;
op.nextOper = oper; op.nextOper = oper;
op.currentTime = 0.0f; op.currentTime = 0.0f;
mChannels[channel]->AddOper(op); m_channels[channel]->AddOper(op);
return true; 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) bool ALSound::Position(int channel, Math::Vector pos)
{ {
if (!mEnabled) if (!m_enabled)
return false; return false;
if (mChannels.find(channel) == mChannels.end()) { if (m_channels.find(channel) == m_channels.end())
{
return false; return false;
} }
if (m3D) { if (m_3D)
mChannels[channel]->SetPan(pos); {
} else { m_channels[channel]->SetPan(pos);
}
else
{
ComputeVolumePan2D(channel, pos); ComputeVolumePan2D(channel, pos);
if (!mChannels[channel]->HasEnvelope()) { if (!m_channels[channel]->HasEnvelope())
float volume = mChannels[channel]->GetStartAmplitude(); {
mChannels[channel]->SetVolume(powf(volume * mChannels[channel]->GetVolumeAtrib(), 0.2f) * mAudioVolume); float volume = m_channels[channel]->GetStartAmplitude();
m_channels[channel]->SetVolume(powf(volume * m_channels[channel]->GetVolumeAtrib(), 0.2f) * m_audioVolume);
} }
} }
return true; return true;
@ -413,29 +451,31 @@ bool ALSound::Position(int channel, Math::Vector pos)
bool ALSound::Frequency(int channel, float frequency) bool ALSound::Frequency(int channel, float frequency)
{ {
if (!mEnabled) if (!m_enabled)
return false; return false;
if (mChannels.find(channel) == mChannels.end()) { if (m_channels.find(channel) == m_channels.end())
{
return false; return false;
} }
mChannels[channel]->SetFrequency(frequency * mChannels[channel]->GetInitFrequency()); m_channels[channel]->SetFrequency(frequency * m_channels[channel]->GetInitFrequency());
mChannels[channel]->SetChangeFrequency(frequency); m_channels[channel]->SetChangeFrequency(frequency);
return true; return true;
} }
bool ALSound::Stop(int channel) bool ALSound::Stop(int channel)
{ {
if (!mEnabled) if (!m_enabled)
return false; return false;
if (mChannels.find(channel) == mChannels.end()) { if (m_channels.find(channel) == m_channels.end())
{
return false; return false;
} }
mChannels[channel]->Stop(); m_channels[channel]->Stop();
mChannels[channel]->ResetOper(); m_channels[channel]->ResetOper();
return true; return true;
} }
@ -443,10 +483,11 @@ bool ALSound::Stop(int channel)
bool ALSound::StopAll() bool ALSound::StopAll()
{ {
if (!mEnabled) if (!m_enabled)
return false; return false;
for (auto channel : mChannels) { for (auto channel : m_channels)
{
channel.second->Stop(); channel.second->Stop();
channel.second->ResetOper(); channel.second->ResetOper();
} }
@ -457,19 +498,24 @@ bool ALSound::StopAll()
bool ALSound::MuteAll(bool bMute) bool ALSound::MuteAll(bool bMute)
{ {
if (!mEnabled) if (!m_enabled)
return false; return false;
for (auto it : mChannels) { for (auto it : m_channels)
if (it.second->IsPlaying()) { {
if (it.second->IsPlaying())
{
it.second->Mute(bMute); it.second->Mute(bMute);
} }
} }
if (bMute) { if (bMute)
mCurrentMusic->SetVolume(0.0f); {
} else { m_currentMusic->SetVolume(0.0f);
mCurrentMusic->SetVolume(mMusicVolume); }
else
{
m_currentMusic->SetVolume(m_musicVolume);
} }
return true; return true;
} }
@ -477,17 +523,20 @@ bool ALSound::MuteAll(bool bMute)
void ALSound::FrameMove(float delta) void ALSound::FrameMove(float delta)
{ {
if (!mEnabled) if (!m_enabled)
return; return;
float progress; float progress;
float volume, frequency; float volume, frequency;
for (auto it : mChannels) { for (auto it : m_channels)
if (!it.second->IsPlaying()) { {
if (!it.second->IsPlaying())
{
continue; continue;
} }
if (it.second->IsMuted()) { if (it.second->IsMuted())
{
it.second->SetVolume(0.0f); it.second->SetVolume(0.0f);
continue; continue;
} }
@ -498,12 +547,12 @@ void ALSound::FrameMove(float delta)
SoundOper &oper = it.second->GetEnvelope(); SoundOper &oper = it.second->GetEnvelope();
oper.currentTime += delta; oper.currentTime += delta;
progress = oper.currentTime / oper.totalTime; progress = oper.currentTime / oper.totalTime;
progress = MIN(progress, 1.0f); progress = std::min(progress, 1.0f);
// setting volume // setting volume
volume = progress * (oper.finalAmplitude - it.second->GetStartAmplitude()); volume = progress * (oper.finalAmplitude - it.second->GetStartAmplitude());
volume = volume + 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 // setting frequency
frequency = progress; frequency = progress;
@ -513,14 +562,19 @@ void ALSound::FrameMove(float delta)
frequency = (frequency * it.second->GetInitFrequency()); frequency = (frequency * it.second->GetInitFrequency());
it.second->SetFrequency(frequency); it.second->SetFrequency(frequency);
if (oper.totalTime <= oper.currentTime) { if (oper.totalTime <= oper.currentTime)
if (oper.nextOper == SOPER_LOOP) { {
if (oper.nextOper == SOPER_LOOP)
{
oper.currentTime = 0.0f; oper.currentTime = 0.0f;
it.second->Play(); it.second->Play();
} else { }
else
{
it.second->SetStartAmplitude(oper.finalAmplitude); it.second->SetStartAmplitude(oper.finalAmplitude);
it.second->SetStartFrequency(oper.finalFrequency); it.second->SetStartFrequency(oper.finalFrequency);
if (oper.nextOper == SOPER_STOP) { if (oper.nextOper == SOPER_STOP)
{
it.second->Stop(); it.second->Stop();
} }
@ -533,26 +587,32 @@ void ALSound::FrameMove(float delta)
void ALSound::SetListener(Math::Vector eye, Math::Vector lookat) void ALSound::SetListener(Math::Vector eye, Math::Vector lookat)
{ {
mEye = eye; m_eye = eye;
mLookat = lookat; m_lookat = lookat;
if (m3D) { if (m_3D)
{
float orientation[] = {lookat.x, lookat.y, lookat.z, 0.f, 1.f, 0.f}; float orientation[] = {lookat.x, lookat.y, lookat.z, 0.f, 1.f, 0.f};
alListener3f(AL_POSITION, eye.x, eye.y, eye.z); alListener3f(AL_POSITION, eye.x, eye.y, eye.z);
alListenerfv(AL_ORIENTATION, orientation); alListenerfv(AL_ORIENTATION, orientation);
} else { }
else
{
float orientation[] = {0.0f, 0.0f, 0.0f, 0.f, 1.f, 0.f}; float orientation[] = {0.0f, 0.0f, 0.0f, 0.f, 1.f, 0.f};
alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f); alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f);
alListenerfv(AL_ORIENTATION, orientation); alListenerfv(AL_ORIENTATION, orientation);
// recalculate sound position // recalculate sound position
for (auto it : mChannels) { for (auto it : m_channels)
if (it.second->IsPlaying()) { {
if (it.second->IsPlaying())
{
Math::Vector pos = it.second->GetPosition(); Math::Vector pos = it.second->GetPosition();
ComputeVolumePan2D(it.first, pos); ComputeVolumePan2D(it.first, pos);
if (!it.second->HasEnvelope()) { if (!it.second->HasEnvelope())
{
float volume = it.second->GetStartAmplitude(); 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) bool ALSound::PlayMusic(std::string filename, bool bRepeat)
{ {
if (!mEnabled) { if (!m_enabled)
{
return false; return false;
} }
@ -576,23 +637,27 @@ bool ALSound::PlayMusic(std::string filename, bool bRepeat)
file << m_soundPath << "/" << filename; file << m_soundPath << "/" << filename;
// check if we have music in cache // 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()); 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()); GetLogger()->Warn("Requested music %s was not found.\n", filename.c_str());
return false; return false;
} }
Buffer *buffer = new Buffer(); Buffer *buffer = new Buffer();
buffer->LoadFromFile(file.str(), static_cast<Sound>(-1)); buffer->LoadFromFile(file.str(), static_cast<Sound>(-1));
mCurrentMusic->SetBuffer(buffer); m_currentMusic->SetBuffer(buffer);
} else { }
else
{
GetLogger()->Debug("Music loaded from cache\n"); GetLogger()->Debug("Music loaded from cache\n");
mCurrentMusic->SetBuffer(mMusic[filename]); m_currentMusic->SetBuffer(m_music[filename]);
} }
mCurrentMusic->SetVolume(mMusicVolume); m_currentMusic->SetVolume(m_musicVolume);
mCurrentMusic->SetLoop(bRepeat); m_currentMusic->SetLoop(bRepeat);
mCurrentMusic->Play(); m_currentMusic->Play();
return true; return true;
} }
@ -600,18 +665,20 @@ bool ALSound::PlayMusic(std::string filename, bool bRepeat)
bool ALSound::RestartMusic() bool ALSound::RestartMusic()
{ {
if (!mEnabled || !mCurrentMusic) { if (!m_enabled || !m_currentMusic)
{
return false; return false;
} }
mCurrentMusic->Stop(); m_currentMusic->Stop();
mCurrentMusic->Play(); m_currentMusic->Play();
return true; return true;
} }
void ALSound::StopMusic() void ALSound::StopMusic()
{ {
if (!mEnabled || !mCurrentMusic) { if (!m_enabled || !m_currentMusic)
{
return; return;
} }
@ -621,70 +688,84 @@ void ALSound::StopMusic()
bool ALSound::IsPlayingMusic() bool ALSound::IsPlayingMusic()
{ {
if (!mEnabled || !mCurrentMusic) { if (!m_enabled || !m_currentMusic)
{
return false; return false;
} }
return mCurrentMusic->IsPlaying(); return m_currentMusic->IsPlaying();
} }
void ALSound::SuspendMusic() void ALSound::SuspendMusic()
{ {
if (!mEnabled || !mCurrentMusic) { if (!m_enabled || !m_currentMusic)
{
return; return;
} }
mCurrentMusic->Stop(); m_currentMusic->Stop();
} }
void ALSound::ComputeVolumePan2D(int channel, Math::Vector &pos) void ALSound::ComputeVolumePan2D(int channel, Math::Vector &pos)
{ {
float dist, a, g; float dist, a, g;
mChannels[channel]->SetPosition(pos); m_channels[channel]->SetPosition(pos);
if (VectorsEqual(pos, mEye)) { if (VectorsEqual(pos, m_eye))
mChannels[channel]->SetVolumeAtrib(1.0f); // maximum volume {
mChannels[channel]->SetPan(Math::Vector()); // at the center m_channels[channel]->SetVolumeAtrib(1.0f); // maximum volume
m_channels[channel]->SetPan(Math::Vector()); // at the center
return; return;
} }
dist = Distance(pos, mEye); dist = Distance(pos, m_eye);
if ( dist >= 110.0f ) { // very far? if ( dist >= 110.0f ) // very far?
mChannels[channel]->SetVolumeAtrib(0.0f); // silence {
mChannels[channel]->SetPan(Math::Vector()); // at the center m_channels[channel]->SetVolumeAtrib(0.0f); // silence
return; m_channels[channel]->SetPan(Math::Vector()); // at the center
} else if ( dist <= 10.0f ) { // very close?
mChannels[channel]->SetVolumeAtrib(1.0f); // maximum volume
mChannels[channel]->SetPan(Math::Vector()); // at the center
return; 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); 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_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 - mEye.x, pos.z - mEye.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); a = fmodf(angle_a, Math::PI * 2.0f);
g = fmodf(angle_g, 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; a += Math::PI * 2.0f;
} }
if ( g < 0.0f ) { if ( g < 0.0f )
{
g += Math::PI * 2.0f; g += Math::PI * 2.0f;
} }
if ( a < g ) { if ( a < g )
if (a + Math::PI * 2.0f - g < g - a ) { {
if (a + Math::PI * 2.0f - g < g - a )
{
a += Math::PI * 2.0f; 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; 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 // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * 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 #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 <map>
#include <string> #include <string>
#include <AL/al.h> #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 class ALSound : public CSoundInterface
{ {
public: public:
ALSound(); ALSound();
~ALSound(); ~ALSound();
bool Create(bool b3D); bool Create(bool b3D);
bool Cache(Sound, std::string); bool Cache(Sound, std::string);
bool CacheMusic(std::string); bool CacheMusic(std::string);
bool GetEnable(); bool GetEnable();
void SetSound3D(bool bMode); void SetSound3D(bool bMode);
bool GetSound3D(); bool GetSound3D();
bool GetSound3DCap(); bool GetSound3DCap();
void SetAudioVolume(int volume); void SetAudioVolume(int volume);
int GetAudioVolume(); int GetAudioVolume();
void SetMusicVolume(int volume); void SetMusicVolume(int volume);
int GetMusicVolume(); int GetMusicVolume();
void SetListener(Math::Vector eye, Math::Vector lookat); void SetListener(Math::Vector eye, Math::Vector lookat);
void FrameMove(float rTime); void FrameMove(float rTime);
int Play(Sound sound, float amplitude=1.0f, float frequency=1.0f, bool bLoop = false); 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); int Play(Sound sound, Math::Vector pos, float amplitude=1.0f, float frequency=1.0f, bool bLoop = false);
bool FlushEnvelope(int channel); bool FlushEnvelope(int channel);
bool AddEnvelope(int channel, float amplitude, float frequency, float time, SoundNext oper); bool AddEnvelope(int channel, float amplitude, float frequency, float time, SoundNext oper);
bool Position(int channel, Math::Vector pos); bool Position(int channel, Math::Vector pos);
bool Frequency(int channel, float frequency); bool Frequency(int channel, float frequency);
bool Stop(int channel); bool Stop(int channel);
bool StopAll(); bool StopAll();
bool MuteAll(bool bMute); bool MuteAll(bool bMute);
bool PlayMusic(int rank, bool bRepeat); bool PlayMusic(int rank, bool bRepeat);
bool PlayMusic(std::string filename, bool bRepeat); bool PlayMusic(std::string filename, bool bRepeat);
bool RestartMusic(); bool RestartMusic();
void SuspendMusic(); void SuspendMusic();
void StopMusic(); void StopMusic();
bool IsPlayingMusic(); bool IsPlayingMusic();
// plugin interface // plugin interface
std::string PluginName(); std::string PluginName();
int PluginVersion(); int PluginVersion();
void InstallPlugin(); void InstallPlugin();
bool UninstallPlugin(std::string &); bool UninstallPlugin(std::string &);
private: private:
void CleanUp(); void CleanUp();
int GetPriority(Sound); int GetPriority(Sound);
bool SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded); bool SearchFreeBuffer(Sound sound, int &channel, bool &bAlreadyLoaded);
void ComputeVolumePan2D(int channel, Math::Vector &pos); void ComputeVolumePan2D(int channel, Math::Vector &pos);
bool mEnabled; bool m_enabled;
bool m3D; bool m_3D;
float mAudioVolume; float m_audioVolume;
float mMusicVolume; float m_musicVolume;
ALCdevice* mDevice; ALCdevice* m_device;
ALCcontext* mContext; ALCcontext* m_context;
std::map<Sound, Buffer*> mSounds; std::map<Sound, Buffer*> m_sounds;
std::map<std::string, Buffer*> mMusic; std::map<std::string, Buffer*> m_music;
std::map<int, Channel*> mChannels; std::map<int, Channel*> m_channels;
Channel *mCurrentMusic; Channel *m_currentMusic;
Math::Vector mEye; Math::Vector m_eye;
Math::Vector mLookat; Math::Vector m_lookat;
}; };

View File

@ -15,25 +15,29 @@
// * along with this program. If not, see http://www.gnu.org/licenses/. // * along with this program. If not, see http://www.gnu.org/licenses/.
#include "buffer.h" #include "sound/oalsound/buffer.h"
Buffer::Buffer() { Buffer::Buffer()
mLoaded = false; {
mDuration = 0.0f; m_loaded = false;
m_duration = 0.0f;
} }
Buffer::~Buffer() { Buffer::~Buffer()
if (mLoaded) { {
alDeleteBuffers(1, &mBuffer); if (m_loaded)
{
alDeleteBuffers(1, &m_buffer);
if (alCheck()) if (alCheck())
GetLogger()->Warn("Failed to unload buffer. Code %d\n", alGetCode()); GetLogger()->Warn("Failed to unload buffer. Code %d\n", alGetCode());
} }
} }
bool Buffer::LoadFromFile(std::string filename, Sound sound) { bool Buffer::LoadFromFile(std::string filename, Sound sound)
mSound = sound; {
m_sound = sound;
GetLogger()->Debug("Loading audio file: %s\n", filename.c_str()); GetLogger()->Debug("Loading audio file: %s\n", filename.c_str());
SF_INFO fileInfo; SF_INFO fileInfo;
@ -45,16 +49,18 @@ bool Buffer::LoadFromFile(std::string filename, Sound sound) {
GetLogger()->Trace(" samplerate %d\n", fileInfo.samplerate); GetLogger()->Trace(" samplerate %d\n", fileInfo.samplerate);
GetLogger()->Trace(" sections %d\n", fileInfo.sections); GetLogger()->Trace(" sections %d\n", fileInfo.sections);
if (!file) { if (!file)
{
GetLogger()->Warn("Could not load file. Reason: %s\n", sf_strerror(file)); GetLogger()->Warn("Could not load file. Reason: %s\n", sf_strerror(file));
mLoaded = false; m_loaded = false;
return false; return false;
} }
alGenBuffers(1, &mBuffer); alGenBuffers(1, &m_buffer);
if (!mBuffer) { if (!m_buffer)
{
GetLogger()->Warn("Could not create audio buffer\n"); GetLogger()->Warn("Could not create audio buffer\n");
mLoaded = false; m_loaded = false;
sf_close(file); sf_close(file);
return false; return false;
} }
@ -64,33 +70,39 @@ bool Buffer::LoadFromFile(std::string filename, Sound sound) {
std::array<int16_t, 4096> buffer; std::array<int16_t, 4096> buffer;
data.reserve(fileInfo.frames); data.reserve(fileInfo.frames);
size_t read = 0; 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); 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); alBufferData(m_buffer, 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; m_duration = static_cast<float>(fileInfo.frames) / fileInfo.samplerate;
mLoaded = true; m_loaded = true;
return true; return true;
} }
Sound Buffer::GetSoundType() { Sound Buffer::GetSoundType()
return mSound; {
return m_sound;
} }
ALuint Buffer::GetBuffer() { ALuint Buffer::GetBuffer()
return mBuffer; {
return m_buffer;
} }
bool Buffer::IsLoaded() { bool Buffer::IsLoaded()
return mLoaded; {
return m_loaded;
} }
float Buffer::GetDuration() { float Buffer::GetDuration()
return mDuration; {
return m_duration;
} }

View File

@ -14,10 +14,18 @@
// * You should have received a copy of the GNU General Public License // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * along with this program. If not, see http://www.gnu.org/licenses/.
// buffer.h /**
* \file buffer.h
* \brief OpenAL buffer
*/
#pragma once #pragma once
#include "sound/sound.h"
#include "common/logger.h"
#include "sound/oalsound/check.h"
#include <string> #include <string>
#include <vector> #include <vector>
#include <array> #include <array>
@ -25,27 +33,23 @@
#include <AL/al.h> #include <AL/al.h>
#include <sndfile.h> #include <sndfile.h>
#include "sound/sound.h"
#include "common/logger.h"
#include "check.h"
class Buffer class Buffer
{ {
public: public:
Buffer(); Buffer();
~Buffer(); ~Buffer();
bool LoadFromFile(std::string, Sound); bool LoadFromFile(std::string, Sound);
bool IsLoaded(); bool IsLoaded();
Sound GetSoundType(); Sound GetSoundType();
ALuint GetBuffer(); ALuint GetBuffer();
float GetDuration(); float GetDuration();
private: private:
ALuint mBuffer; ALuint m_buffer;
Sound mSound; Sound m_sound;
bool mLoaded; bool m_loaded;
float mDuration; float m_duration;
}; };

View File

@ -15,37 +15,41 @@
// * along with this program. If not, see http://www.gnu.org/licenses/. // * along with this program. If not, see http://www.gnu.org/licenses/.
#include "channel.h" #include "sound/oalsound/channel.h"
Channel::Channel() Channel::Channel()
{ {
alGenSources(1, &mSource); alGenSources(1, &m_source);
if (alCheck()) { if (alCheck())
{
GetLogger()->Warn("Failed to create sound source. Code: %d\n", alGetCode()); GetLogger()->Warn("Failed to create sound source. Code: %d\n", alGetCode());
mReady = false; m_ready = false;
} else { }
mReady = true; else
{
m_ready = true;
} }
mPriority = 0; m_priority = 0;
mBuffer = nullptr; m_buffer = nullptr;
mLoop = false; m_loop = false;
mMute = false; m_mute = false;
mInitFrequency = 0.0f; m_initFrequency = 0.0f;
mStartAmplitude = 0.0f; m_startAmplitude = 0.0f;
mStartFrequency = 0.0f; m_startFrequency = 0.0f;
mChangeFrequency = 0.0f; m_changeFrequency = 0.0f;
mVolume = 0.0f; m_volume = 0.0f;
} }
Channel::~Channel() Channel::~Channel()
{ {
if (mReady) { if (m_ready)
alSourceStop(mSource); {
alSourcei(mSource, AL_BUFFER, 0); alSourceStop(m_source);
alDeleteSources(1, &mSource); alSourcei(m_source, AL_BUFFER, 0);
alDeleteSources(1, &m_source);
if (alCheck()) if (alCheck())
GetLogger()->Warn("Failed to delete sound source. Code: %d\n", alGetCode()); GetLogger()->Warn("Failed to delete sound source. Code: %d\n", alGetCode());
} }
@ -54,15 +58,17 @@ Channel::~Channel()
bool Channel::Play() bool Channel::Play()
{ {
if (!mReady || mBuffer == nullptr) { if (!m_ready || m_buffer == nullptr)
{
return false; return false;
} }
alSourcei(mSource, AL_LOOPING, static_cast<ALint>(mLoop)); alSourcei(m_source, AL_LOOPING, static_cast<ALint>(m_loop));
alSourcei(mSource, AL_REFERENCE_DISTANCE, 10.0f); alSourcei(m_source, AL_REFERENCE_DISTANCE, 10.0f);
alSourcei(mSource, AL_MAX_DISTANCE, 110.0f); alSourcei(m_source, AL_MAX_DISTANCE, 110.0f);
alSourcePlay(mSource); alSourcePlay(m_source);
if (alCheck()) { if (alCheck())
{
GetLogger()->Warn("Could not play audio sound source. Code: %d\n", alGetCode()); GetLogger()->Warn("Could not play audio sound source. Code: %d\n", alGetCode());
} }
return true; return true;
@ -71,12 +77,14 @@ bool Channel::Play()
bool Channel::SetPan(Math::Vector pos) bool Channel::SetPan(Math::Vector pos)
{ {
if (!mReady || mBuffer == nullptr) { if (!m_ready || m_buffer == nullptr)
{
return false; return false;
} }
alSource3f(mSource, AL_POSITION, pos.x, pos.y, pos.z); alSource3f(m_source, AL_POSITION, pos.x, pos.y, pos.z);
if (alCheck()) { if (alCheck())
{
GetLogger()->Warn("Could not set sound position. Code: %d\n", alGetCode()); GetLogger()->Warn("Could not set sound position. Code: %d\n", alGetCode());
return false; return false;
} }
@ -86,24 +94,26 @@ bool Channel::SetPan(Math::Vector pos)
void Channel::SetPosition(Math::Vector pos) void Channel::SetPosition(Math::Vector pos)
{ {
mPosition = pos; m_position = pos;
} }
Math::Vector Channel::GetPosition() Math::Vector Channel::GetPosition()
{ {
return mPosition; return m_position;
} }
bool Channel::SetFrequency(float freq) bool Channel::SetFrequency(float freq)
{ {
if (!mReady || mBuffer == nullptr) { if (!m_ready || m_buffer == nullptr)
{
return false; return false;
} }
alSourcef(mSource, AL_PITCH, freq); alSourcef(m_source, AL_PITCH, freq);
if (alCheck()) { if (alCheck())
{
GetLogger()->Warn("Could not set sound pitch to '%f'. Code: %d\n", freq, alGetCode()); GetLogger()->Warn("Could not set sound pitch to '%f'. Code: %d\n", freq, alGetCode());
return false; return false;
} }
@ -114,12 +124,14 @@ bool Channel::SetFrequency(float freq)
float Channel::GetFrequency() float Channel::GetFrequency()
{ {
ALfloat freq; ALfloat freq;
if (!mReady || mBuffer == nullptr) { if (!m_ready || m_buffer == nullptr)
{
return 0; return 0;
} }
alGetSourcef(mSource, AL_PITCH, &freq); alGetSourcef(m_source, AL_PITCH, &freq);
if (alCheck()) { if (alCheck())
{
GetLogger()->Warn("Could not get sound pitch. Code: %d\n", alGetCode()); GetLogger()->Warn("Could not get sound pitch. Code: %d\n", alGetCode());
return 0; return 0;
} }
@ -130,12 +142,14 @@ float Channel::GetFrequency()
bool Channel::SetVolume(float vol) bool Channel::SetVolume(float vol)
{ {
if (!mReady || vol < 0 || mBuffer == nullptr) { if (!m_ready || vol < 0 || m_buffer == nullptr)
{
return false; return false;
} }
alSourcef(mSource, AL_GAIN, vol); alSourcef(m_source, AL_GAIN, vol);
if (alCheck()) { if (alCheck())
{
GetLogger()->Warn("Could not set sound volume to '%f'. Code: %d\n", vol, alGetCode()); GetLogger()->Warn("Could not set sound volume to '%f'. Code: %d\n", vol, alGetCode());
return false; return false;
} }
@ -146,12 +160,14 @@ bool Channel::SetVolume(float vol)
float Channel::GetVolume() float Channel::GetVolume()
{ {
ALfloat vol; ALfloat vol;
if (!mReady || mBuffer == nullptr) { if (!m_ready || m_buffer == nullptr)
{
return 0; return 0;
} }
alGetSourcef(mSource, AL_GAIN, &vol); alGetSourcef(m_source, AL_GAIN, &vol);
if (alCheck()) { if (alCheck())
{
GetLogger()->Warn("Could not get sound volume. Code: %d\n", alGetCode()); GetLogger()->Warn("Could not get sound volume. Code: %d\n", alGetCode());
return 0; return 0;
} }
@ -162,134 +178,144 @@ float Channel::GetVolume()
void Channel::SetVolumeAtrib(float volume) void Channel::SetVolumeAtrib(float volume)
{ {
mVolume = volume; m_volume = volume;
} }
float Channel::GetVolumeAtrib() float Channel::GetVolumeAtrib()
{ {
return mVolume; return m_volume;
} }
int Channel::GetPriority() int Channel::GetPriority()
{ {
return mPriority; return m_priority;
} }
void Channel::SetPriority(int pri) void Channel::SetPriority(int pri)
{ {
mPriority = pri; m_priority = pri;
} }
void Channel::SetStartAmplitude(float gain) void Channel::SetStartAmplitude(float gain)
{ {
mStartAmplitude = gain; m_startAmplitude = gain;
} }
void Channel::SetStartFrequency(float freq) void Channel::SetStartFrequency(float freq)
{ {
mStartFrequency = freq; m_startFrequency = freq;
} }
void Channel::SetChangeFrequency(float freq) void Channel::SetChangeFrequency(float freq)
{ {
mChangeFrequency = freq; m_changeFrequency = freq;
} }
float Channel::GetStartAmplitude() float Channel::GetStartAmplitude()
{ {
return mStartAmplitude; return m_startAmplitude;
} }
float Channel::GetStartFrequency() float Channel::GetStartFrequency()
{ {
return mStartFrequency; return m_startFrequency;
} }
float Channel::GetChangeFrequency() float Channel::GetChangeFrequency()
{ {
return mChangeFrequency; return m_changeFrequency;
} }
float Channel::GetInitFrequency() float Channel::GetInitFrequency()
{ {
return mInitFrequency; return m_initFrequency;
} }
void Channel::AddOper(SoundOper oper) void Channel::AddOper(SoundOper oper)
{ {
mOper.push_back(oper); m_oper.push_back(oper);
} }
void Channel::ResetOper() void Channel::ResetOper()
{ {
mOper.clear(); m_oper.clear();
} }
Sound Channel::GetSoundType() { Sound Channel::GetSoundType()
if (!mReady || mBuffer == nullptr) { {
if (!m_ready || m_buffer == nullptr)
{
return SOUND_NONE; return SOUND_NONE;
} }
return mBuffer->GetSoundType(); return m_buffer->GetSoundType();
} }
bool Channel::SetBuffer(Buffer *buffer) { bool Channel::SetBuffer(Buffer *buffer)
if (!mReady) {
if (!m_ready)
return false; return false;
Stop(); Stop();
mBuffer = buffer; m_buffer = buffer;
if (buffer == nullptr) { if (buffer == nullptr)
alSourcei(mSource, AL_BUFFER, 0); {
alSourcei(m_source, AL_BUFFER, 0);
return true; return true;
} }
alSourcei(mSource, AL_BUFFER, buffer->GetBuffer()); alSourcei(m_source, AL_BUFFER, buffer->GetBuffer());
if (alCheck()) { if (alCheck())
{
GetLogger()->Warn("Could not set sound buffer. Code: %d\n", alGetCode()); GetLogger()->Warn("Could not set sound buffer. Code: %d\n", alGetCode());
return false; return false;
} }
mInitFrequency = GetFrequency(); m_initFrequency = GetFrequency();
return true; return true;
} }
bool Channel::FreeBuffer() { bool Channel::FreeBuffer()
if (!mReady || !mBuffer) { {
if (!m_ready || !m_buffer)
{
return false; return false;
} }
alSourceStop(mSource); alSourceStop(m_source);
alSourcei(mSource, AL_BUFFER, 0); alSourcei(m_source, AL_BUFFER, 0);
delete mBuffer; delete m_buffer;
mBuffer = nullptr; m_buffer = nullptr;
return true; return true;
} }
bool Channel::IsPlaying() { bool Channel::IsPlaying()
{
ALint status; ALint status;
if (!mReady || mBuffer == nullptr) { if (!m_ready || m_buffer == nullptr)
{
return false; return false;
} }
alGetSourcei(mSource, AL_SOURCE_STATE, &status); alGetSourcei(m_source, AL_SOURCE_STATE, &status);
if (alCheck()) { if (alCheck())
{
GetLogger()->Warn("Could not get sound status. Code: %d\n", alGetCode()); GetLogger()->Warn("Could not get sound status. Code: %d\n", alGetCode());
return false; return false;
} }
@ -298,22 +324,27 @@ bool Channel::IsPlaying() {
} }
bool Channel::IsReady() { bool Channel::IsReady()
return mReady; {
return m_ready;
} }
bool Channel::IsLoaded() { bool Channel::IsLoaded()
return mBuffer != nullptr; {
return m_buffer != nullptr;
} }
bool Channel::Stop() { bool Channel::Stop()
if (!mReady || mBuffer == nullptr) { {
if (!m_ready || m_buffer == nullptr)
{
return false; return false;
} }
alSourceStop(mSource); alSourceStop(m_source);
if (alCheck()) { if (alCheck())
{
GetLogger()->Warn("Could not stop sound. Code: %d\n", alGetCode()); GetLogger()->Warn("Could not stop sound. Code: %d\n", alGetCode());
return false; return false;
} }
@ -323,13 +354,15 @@ bool Channel::Stop() {
float Channel::GetCurrentTime() float Channel::GetCurrentTime()
{ {
if (!mReady || mBuffer == nullptr) { if (!m_ready || m_buffer == nullptr)
{
return 0.0f; return 0.0f;
} }
ALfloat current; ALfloat current;
alGetSourcef(mSource, AL_SEC_OFFSET, &current); alGetSourcef(m_source, AL_SEC_OFFSET, &current);
if (alCheck()) { if (alCheck())
{
GetLogger()->Warn("Could not get source current play time. Code: %d\n", alGetCode()); GetLogger()->Warn("Could not get source current play time. Code: %d\n", alGetCode());
return 0.0f; return 0.0f;
} }
@ -339,12 +372,14 @@ float Channel::GetCurrentTime()
void Channel::SetCurrentTime(float current) void Channel::SetCurrentTime(float current)
{ {
if (!mReady || mBuffer == nullptr) { if (!m_ready || m_buffer == nullptr)
{
return; return;
} }
alSourcef(mSource, AL_SEC_OFFSET, current); alSourcef(m_source, AL_SEC_OFFSET, current);
if (alCheck()) { if (alCheck())
{
GetLogger()->Warn("Could not get source current play time. Code: %d\n", alGetCode()); 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() float Channel::GetDuration()
{ {
if (!mReady || mBuffer == nullptr) { if (!m_ready || m_buffer == nullptr)
{
return 0.0f; return 0.0f;
} }
return mBuffer->GetDuration(); return m_buffer->GetDuration();
} }
bool Channel::HasEnvelope() bool Channel::HasEnvelope()
{ {
return mOper.size() > 0; return m_oper.size() > 0;
} }
SoundOper& Channel::GetEnvelope() SoundOper& Channel::GetEnvelope()
{ {
return mOper.front(); return m_oper.front();
} }
void Channel::PopEnvelope() void Channel::PopEnvelope()
{ {
mOper.pop_front(); m_oper.pop_front();
} }
void Channel::SetLoop(bool loop) { void Channel::SetLoop(bool loop)
mLoop = loop; {
m_loop = loop;
} }
void Channel::Mute(bool mute) void Channel::Mute(bool mute)
{ {
mMute = mute; m_mute = mute;
} }
bool Channel::IsMuted() 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 // * You should have received a copy of the GNU General Public License
// * along with this program. If not, see http://www.gnu.org/licenses/. // * along with this program. If not, see http://www.gnu.org/licenses/.
// channel.h /**
* \file channel.h
* \brief OpenAL channel
*/
#pragma once #pragma once
#include "sound/sound.h"
#include "sound/oalsound/buffer.h"
#include "sound/oalsound/check.h"
#include <string> #include <string>
#include <deque> #include <deque>
#include <cassert> #include <cassert>
@ -25,11 +33,6 @@
#include <AL/al.h> #include <AL/al.h>
#include <AL/alc.h> #include <AL/alc.h>
#include "sound/sound.h"
#include "buffer.h"
#include "check.h"
struct SoundOper struct SoundOper
{ {
float finalAmplitude; float finalAmplitude;
@ -42,72 +45,73 @@ struct SoundOper
class Channel class Channel
{ {
public: public:
Channel(); Channel();
~Channel(); ~Channel();
bool Play(); bool Play();
bool Stop(); bool Stop();
bool SetPan(Math::Vector); bool SetPan(Math::Vector);
void SetPosition(Math::Vector); void SetPosition(Math::Vector);
Math::Vector GetPosition(); Math::Vector GetPosition();
bool SetFrequency(float); bool SetFrequency(float);
float GetFrequency(); float GetFrequency();
float GetCurrentTime(); float GetCurrentTime();
void SetCurrentTime(float); void SetCurrentTime(float);
float GetDuration(); float GetDuration();
bool SetVolume(float); bool SetVolume(float);
float GetVolume(); float GetVolume();
void SetVolumeAtrib(float); void SetVolumeAtrib(float);
float GetVolumeAtrib(); float GetVolumeAtrib();
bool IsPlaying(); bool IsPlaying();
bool IsReady(); bool IsReady();
bool IsLoaded(); bool IsLoaded();
bool SetBuffer(Buffer *); bool SetBuffer(Buffer *);
bool FreeBuffer(); bool FreeBuffer();
bool HasEnvelope(); bool HasEnvelope();
SoundOper& GetEnvelope(); SoundOper& GetEnvelope();
void PopEnvelope(); void PopEnvelope();
int GetPriority(); int GetPriority();
void SetPriority(int); void SetPriority(int);
void SetStartAmplitude(float); void SetStartAmplitude(float);
void SetStartFrequency(float); void SetStartFrequency(float);
void SetChangeFrequency(float); void SetChangeFrequency(float);
float GetStartAmplitude(); float GetStartAmplitude();
float GetStartFrequency(); float GetStartFrequency();
float GetChangeFrequency(); float GetChangeFrequency();
float GetInitFrequency(); float GetInitFrequency();
void AddOper(SoundOper); void AddOper(SoundOper);
void ResetOper(); void ResetOper();
Sound GetSoundType(); Sound GetSoundType();
void SetLoop(bool); void SetLoop(bool);
void Mute(bool); void Mute(bool);
bool IsMuted(); bool IsMuted();
private: private:
Buffer *mBuffer; Buffer *m_buffer;
ALuint mSource; ALuint m_source;
int mPriority; int m_priority;
float mStartAmplitude; float m_startAmplitude;
float mStartFrequency; float m_startFrequency;
float mChangeFrequency; float m_changeFrequency;
float mInitFrequency; float m_initFrequency;
float mVolume; float m_volume;
std::deque<SoundOper> mOper; std::deque<SoundOper> m_oper;
bool mReady; bool m_ready;
bool mLoop; bool m_loop;
bool mMute; bool m_mute;
Math::Vector mPosition; Math::Vector m_position;
}; };

View File

@ -37,3 +37,4 @@ inline ALenum alGetCode()
CODE = AL_NO_ERROR; CODE = AL_NO_ERROR;
return ret; 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 #pragma once
#include <boost/filesystem.hpp>
#include "math/vector.h" #include "math/vector.h"
#include "common/logger.h" #include "common/logger.h"
#include <string> #include <string>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <map>
/*! /*!
* Maximum possible audio volume * 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_EXPLOg1 = 79, /*!< impact gun 1 */
SOUND_EXPLOg2 = 80, /*!< impact gun 2 */ SOUND_EXPLOg2 = 80, /*!< impact gun 2 */
// SOUND_MOTORd = 81, /*!< engine friction */ // SOUND_MOTORd = 81, /*!< engine friction */
SOUND_MAX /** number of items in enum */
}; };
@ -154,35 +148,22 @@ enum SoundNext
*/ */
class CSoundInterface class CSoundInterface
{ {
public: public:
inline CSoundInterface() {} CSoundInterface();
inline virtual ~CSoundInterface() {} virtual ~CSoundInterface();
/** Function to initialize sound device /** Function to initialize sound device
* \param b3D - enable support for 3D sound * \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 called to cache all sound effect files.
* Function calls \link CSoundInterface::Cache() \endlink for each file * Function calls \link CSoundInterface::Cache() \endlink for each file
*/ */
inline void CacheAll(std::string path) { 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());
}
};
/** Function called to add all music files to list */ /** Function called to add all music files to list */
inline void AddMusicFiles(std::string path) { void AddMusicFiles(std::string path);
m_soundPath = path;
CacheMusic("Intro1.ogg");
CacheMusic("Intro2.ogg");
CacheMusic("music010.ogg");
CacheMusic("music011.ogg");
};
/** Function called to cache sound effect file. /** Function called to cache sound effect file.
* This function is called by plugin interface for each file. * This function is called by plugin interface for each file.
@ -190,65 +171,65 @@ class CSoundInterface
* \param bFile - file to load * \param bFile - file to load
* \return return true on success * \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. /** Function called to cache music file.
* This function is called by CRobotMain for each file used in the mission. * This function is called by CRobotMain for each file used in the mission.
* \param bFile - file to load * \param bFile - file to load
* \return return true on success * \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 if plugin is enabled
* \return return true 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 /** Change sound mode to 2D/3D
* \param bMode - true to enable 3D sound * \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 if we use 3D sound
* \return true if we have 3D sound enabled * \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 if we have 3D sound capable card
* \return true for 3D sound support * \return true for 3D sound support
*/ */
inline virtual bool GetSound3DCap() {return true;}; virtual bool GetSound3DCap();
/** Change global sound volume /** Change global sound volume
* \param volume - range from 0 to MAXVOLUME * \param volume - range from 0 to MAXVOLUME
*/ */
inline virtual void SetAudioVolume(int volume) {}; virtual void SetAudioVolume(int volume);
/** Return global sound volume /** Return global sound volume
* \return global volume as int in range from 0 to MAXVOLUME * \return global volume as int in range from 0 to MAXVOLUME
*/ */
inline virtual int GetAudioVolume() {return 0;}; virtual int GetAudioVolume();
/** Set music volume /** Set music volume
* \param volume - range from 0 to MAXVOLUME * \param volume - range from 0 to MAXVOLUME
*/ */
inline virtual void SetMusicVolume(int volume) {}; virtual void SetMusicVolume(int volume);
/** Return music volume /** Return music volume
* \return music volume as int in range from 0 to MAXVOLUME * \return music volume as int in range from 0 to MAXVOLUME
*/ */
inline virtual int GetMusicVolume() {return 0;}; virtual int GetMusicVolume();
/** Set listener position /** Set listener position
* \param eye - position of listener * \param eye - position of listener
* \param lookat - direction listener is looking at * \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 /** Update data each frame
* \param rTime - time since last update * \param rTime - time since last update
*/ */
inline virtual void FrameMove(float rTime) {}; virtual void FrameMove(float rTime);
/** Play specific sound /** Play specific sound
* \param sound - sound to play * \param sound - sound to play
@ -257,7 +238,7 @@ class CSoundInterface
* \param bLoop - loop sound * \param bLoop - loop sound
* \return identifier of channel that sound will be played on * \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 /** Play specific sound
* \param sound - sound to play * \param sound - sound to play
@ -267,13 +248,13 @@ class CSoundInterface
* \param bLoop - loop sound * \param bLoop - loop sound
* \return identifier of channel that sound will be played on * \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. /** Remove all operations that would be made on sound in channel.
* \param channel - channel to work on * \param channel - channel to work on
* \return return true on success * \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 /** 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 * \param channel - channel to work on
@ -283,74 +264,74 @@ class CSoundInterface
* \param oper - operation to perform * \param oper - operation to perform
* \return return true on success * \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 /** Set sound position in space
* \param channel - channel to work on * \param channel - channel to work on
* \param pos - new positino of a sound * \param pos - new positino of a sound
* \return return true on success * \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 /** Set sound frequency
* \param channel - channel to work on * \param channel - channel to work on
* \param frequency - change sound frequency * \param frequency - change sound frequency
* \return return true on success * \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 /** Stop playing sound
* \param channel - channel to work on * \param channel - channel to work on
* \return return true on success * \return return true on success
*/ */
inline virtual bool Stop(int channel) {return true;}; virtual bool Stop(int channel);
/** Stop playing all sounds /** Stop playing all sounds
* \return return true on success * \return return true on success
*/ */
inline virtual bool StopAll() {return true;}; virtual bool StopAll();
/** Mute/unmute all sounds /** Mute/unmute all sounds
* \param bMute * \param bMute
* \return return true on success * \return return true on success
*/ */
inline virtual bool MuteAll(bool bMute) {return true;}; virtual bool MuteAll(bool bMute);
/** Start playing music /** Start playing music
* \param rank - track number * \param rank - track number
* \param bRepeat - repeat playing * \param bRepeat - repeat playing
* \return return true on success * \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 /** Start playing music
* \param filename - name of file to play * \param filename - name of file to play
* \param bRepeat - repeat playing * \param bRepeat - repeat playing
* \return return true on success * \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 /** Restart music
* @return return true on success * @return return true on success
*/ */
inline virtual bool RestartMusic() {return true;}; virtual bool RestartMusic();
/** Susspend paying music /** Susspend paying music
* \return return true on success * \return return true on success
*/ */
inline virtual void SuspendMusic() {}; virtual void SuspendMusic();
/** Stop playing music /** Stop playing music
* \return return true on success * \return return true on success
*/ */
inline virtual void StopMusic() {}; virtual void StopMusic();
/** Check if music if playing /** Check if music if playing
* \return return true if music is playing * \return return true if music is playing
*/ */
inline virtual bool IsPlayingMusic() {return true;}; virtual bool IsPlayingMusic();
protected: protected:
std::string m_soundPath; std::string m_soundPath;
}; };

View File

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