Commit 56b1ffb9 authored by Florian Oetke's avatar Florian Oetke
Browse files

added sound effects

parent 047dc7aa
audio: = audio/
audio: = audio/*.opus
cfg:sound_effects = settings/sound_effects.json
{
"effects": {
"dash": ["dash3"],
"attack": ["stationary_attack"],
"e_att_h": ["enemy_attack_heavy"],
"e_att_s": ["enemy_attack_small"],
"enemy_hit": ["enemy_hit_1", "enemy_hit_2", "enemy_hit_3", "enemy_hit_4", "enemy_hit_5"],
"gameover": ["gameover"],
"damaged": ["player_damaged"],
"win": ["win", "win2"]
}
}
#include "sound_manager.hpp"
#include "audio_asset.hpp"
#include "../messages.hpp"
#include <mirrage/utils/random.hpp>
namespace phase_shifter::audio {
struct Effect_file {
std::unordered_map<std::string, std::vector<std::string>> effects;
};
sf2_structDef(Effect_file, effects);
Sound_manager::Sound_manager(eam::audio& audio,
mirrage::util::Message_bus& bus,
mirrage::asset::Asset_manager& assets)
: _audio(audio), _mailbox(bus), _assets(assets), _random_gen(mirrage::util::construct_random_engine())
{
_mailbox.subscribe_to([&](Play_sound_msg& e) { play_effect(e.id); });
}
void Sound_manager::load_effects_file(const mirrage::asset::AID& aid)
{
auto file = _assets.load<Effect_file>(aid, false);
for(auto&& [id, paths] : file.get_blocking().effects) {
for(auto&& path : paths)
register_effect(Sound_effect_id(id), mirrage::asset::AID("audio"_strid, path));
}
}
void Sound_manager::effect_volume(float v) { _effect_volume = v; }
void Sound_manager::pause()
{
// TODO
}
void Sound_manager::resume()
{
// TODO
}
void Sound_manager::update(mirrage::util::Time dt) { _mailbox.update_subscriptions(); }
void Sound_manager::register_effect(Sound_effect_id id, const mirrage::asset::AID& aid)
{
LOG(plog::info) << "Loading sound " << aid.str();
auto effect = _assets.load<std::shared_ptr<eam::opus>>(aid).get_blocking();
auto entry = _sound_effects.find(id);
if(entry != _sound_effects.end())
entry->second.raw_vector().emplace_back(std::move(effect));
else {
auto effects = Sound_effect_set();
effects.raw_vector().emplace_back(std::move(effect));
_sound_effects.emplace(id, std::move(effects));
}
}
void Sound_manager::unregister_effect(Sound_effect_id id) { _sound_effects.erase(id); }
void Sound_manager::play_effect(Sound_effect_id id)
{
auto effect = _sound_effects.find(id);
if(effect != _sound_effects.end()) {
auto ctx = _audio.generate_context(effect->second.get_random(_random_gen));
ctx.get_object()->set_loops(0);
ctx.get_object()->set_volume(_effect_volume * 100);
ctx.play();
}
}
} // namespace phase_shifter::audio
#pragma once
#include "../util/random_vector.hpp"
#include <mirrage/asset/asset_manager.hpp>
#include <mirrage/utils/messagebus.hpp>
#include <mirrage/utils/str_id.hpp>
#include <mirrage/utils/units.hpp>
#include <audio.hpp>
#include <memory>
#include <random>
#include <string>
#include <unordered_map>
namespace phase_shifter::audio {
using Sound_effect_id = mirrage::util::Str_id;
class Sound_manager {
public:
Sound_manager(eam::audio& audio, mirrage::util::Message_bus&, mirrage::asset::Asset_manager&);
void load_effects_file(const mirrage::asset::AID& aid);
void effect_volume(float);
auto effect_volume() const -> float { return _effect_volume; }
void pause();
void resume();
void update(mirrage::util::Time dt);
void register_effect(Sound_effect_id id, const mirrage::asset::AID& aid);
void unregister_effect(Sound_effect_id id);
void play_effect(Sound_effect_id id);
private:
using Sound_effect = std::shared_ptr<eam::opus>;
using Sound_effect_set = utils::Random_vector<Sound_effect>;
eam::audio& _audio;
mirrage::util::Mailbox_collection _mailbox;
mirrage::asset::Asset_manager& _assets;
float _effect_volume = 1.f;
std::mt19937_64 _random_gen;
std::unordered_map<Sound_effect_id, Sound_effect_set> _sound_effects;
};
} // namespace phase_shifter::audio
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment