spacebox/src/Audio.cpp

136 lines
2.5 KiB
C++

#include "Audio.hpp"
BGM::BGM(Node* parent) : Node(parent) {}
BGM::BGM() : BGM(nullptr) {}
BGM::BGM(Node* parent, const fs::path& path) : BGM(parent)
{
load_music(path);
}
BGM::BGM(const fs::path& path) : BGM(nullptr, path) {}
void BGM::load_music(const fs::path& path)
{
music = Mix_LoadMUS(path.c_str());
}
void BGM::set_volume(float v)
{
volume = v;
}
void BGM::play(int loops)
{
Mix_VolumeMusic(std::round(volume * 127));
Mix_PlayMusic(music, loops);
}
BGM::~BGM()
{
Mix_FreeMusic(music);
}
SoundEffect::SoundEffect(Node* parent) : Node(parent) {}
SoundEffect::SoundEffect() : SoundEffect(nullptr) {}
SoundEffect::SoundEffect(Node* parent, const fs::path& path) : SoundEffect(parent)
{
load_chunk(path);
}
SoundEffect::SoundEffect(const fs::path& path) : SoundEffect(nullptr, path) {}
void SoundEffect::load_chunk(const fs::path& path)
{
chunk = Mix_LoadWAV(path.c_str());
Mix_VolumeChunk(chunk, std::round(volume * 127));
}
void SoundEffect::play(float location)
{
play();
Box window = window_box();
location = std::clamp(location, window.left(), window.right());
float location_relative = (location - window.left()) / window.width();
int angle = 270 - location_relative * 180;
Mix_SetPosition(channel, angle, 0);
}
void SoundEffect::play()
{
channel = Mix_PlayChannel(-1, chunk, loops);
}
void SoundEffect::play_after(float delay)
{
play_animation.play_once(delay);
}
void SoundEffect::set_volume(float v)
{
volume = v;
Mix_VolumeChunk(chunk, std::round(volume * 127));
}
void SoundEffect::set_loop_count(int count)
{
loops = count;
}
void SoundEffect::set_loop_forever()
{
loops = -1;
}
bool SoundEffect::playing(bool include_delay) const
{
if (include_delay)
{
if (play_animation.playing())
{
return true;
}
}
for (int channel_ii = 0; channel_ii < Mix_GroupAvailable(-1); channel_ii++)
{
if (Mix_GetChunk(channel_ii) == chunk)
{
return true;
}
}
return false;
}
void SoundEffect::update()
{
play_animation.update();
}
SoundEffect::~SoundEffect()
{
Mix_FreeChunk(chunk);
}
Audio::Audio(Node* parent) : Node(parent) {}
void Audio::load_sfx()
{
load_directory(configuration()["audio"]["default-sfx-root"], sfx, this);
}
void Audio::load_bgm()
{
load_directory(configuration()["audio"]["default-bgm-root"], bgm, this);
}
void Audio::update()
{
for (auto& [name, sound_effect] : sfx)
{
sound_effect.update();
}
}