fekalnigtacko/src/audio/master.cpp
2026-01-10 12:51:53 +01:00

123 lines
3.1 KiB
C++

#include "master.hpp"
#include <iostream>
#include "defs.hpp"
#include "sound_source.hpp"
#include "source.hpp"
static const size_t MAX_CATEGORIES = 32;
audio::Master::Master()
{
std::cout << "Initializing audio master...\n";
categories_.reserve(MAX_CATEGORIES);
device_ = alcOpenDevice(nullptr);
if (!device_)
{
throw std::runtime_error("(AL) Failed to open audio device");
}
// get device info
const ALchar* info = alcGetString(device_, ALC_DEVICE_SPECIFIER);
std::cout << "Opened audio device: " << (info ? info : "Unknown") << std::endl;
context_ = alcCreateContext(device_, nullptr);
if (!context_)
{
alcCloseDevice(device_);
device_ = nullptr;
throw std::runtime_error("(AL) Failed to create audio context");
}
std::cout << "Created audio context" << std::endl;
if (!alcMakeContextCurrent(context_))
{
alcDestroyContext(context_);
alcCloseDevice(device_);
context_ = nullptr;
device_ = nullptr;
throw std::runtime_error("(AL) Failed to make audio context current");
}
std::cout << "Audio context is now current" << std::endl;
}
void audio::Master::SetListenerOrientation(const glm::vec3& position, const glm::vec3& forward, const glm::vec3& up)
{
alListener3f(AL_POSITION, position.x, position.y, position.z);
// alListener3f(AL_VELOCITY, 0.0f, 0.0f, 0.0f);
ALfloat orientation[] = {forward.x, forward.y, forward.z, up.x, up.y, up.z};
alListenerfv(AL_ORIENTATION, orientation);
}
void audio::Master::SetListenerOrientation(const glm::mat4& world_matrix)
{
glm::vec3 position = glm::vec3(world_matrix[3]);
glm::vec3 forward = -glm::normalize(glm::vec3(world_matrix[2]));
glm::vec3 up = glm::normalize(glm::vec3(world_matrix[1]));
SetListenerOrientation(position, forward, up);
}
audio::Category* audio::Master::GetCategory(const std::string& name)
{
auto it = category_map_.find(name);
if (it != category_map_.end())
{
return it->second;
}
if (categories_.size() >= MAX_CATEGORIES)
{
throw std::runtime_error("(AL) Maximum number of audio categories reached");
}
Category* new_category = &categories_.emplace_back(name);
category_map_[name] = new_category;
AUDIO_DBG(std::cout << "Created new audio category: " << name << std::endl;)
return new_category;
}
void audio::Master::SetMasterVolume(float volume)
{
master_volume_ = volume;
alListenerf(AL_GAIN, master_volume_);
AUDIO_DBG(std::cout << "Set master volume to " << master_volume_ << std::endl;)
}
audio::Master::~Master()
{
std::cout << "Shutting down audio master...\n";
if (context_)
{
alcMakeContextCurrent(nullptr);
alcDestroyContext(context_);
context_ = nullptr;
}
if (device_)
{
alcCloseDevice(device_);
device_ = nullptr;
}
}
audio::Category::Category(const std::string& name) : name_(name) {}
void audio::Category::SetVolume(float volume)
{
volume_ = volume;
for (Source* source = first_source_; source; source = source->cat_next_)
{
source->UpdateVolume();
}
}