initial commit

This commit is contained in:
NeilClack
2026-08-07 14:51:41 -05:00
commit 9251b3a196
604 changed files with 464448 additions and 0 deletions
+93
View File
@@ -0,0 +1,93 @@
#pragma once
#include "config/config_manager.h"
#include <SDL3_mixer/SDL_mixer.h>
#include <mutex>
#include <string>
#include <vector>
namespace radiantwave::audio {
struct AudioDeviceItem {
std::string raw_name; // e.g. alsa_output.pci-0000_00_1f.3.analog-stereo
std::string friendly_name; // e.g. "Built-In Speakers"
};
// Maps raw technical audio device strings to user-friendly labels
std::string mapToFriendlyDeviceName(const std::string& raw_name);
class AudioManager {
public:
AudioManager();
~AudioManager();
// Non-copyable
AudioManager(const AudioManager&) = delete;
AudioManager& operator=(const AudioManager&) = delete;
// Initialize SDL3_mixer audio system
bool initialize(config::ConfigManager& config);
// Shutdown audio subsystem
void shutdown();
// Enumerate playback devices with friendly names
std::vector<AudioDeviceItem> getPlaybackDevices() const;
// Master volume control (0 - 100)
void setVolume(int volume_0_to_100);
int getVolume() const;
// Master audio enable / mute toggle
void setAudioEnabled(bool enabled);
bool isAudioEnabled() const;
// Audio device selection
bool switchDevice(const std::string& raw_device_name);
std::string getCurrentDevice() const;
// Playback control
bool playTrack(const std::string& wav_filename);
void stopTrack();
// Filename of the track currently loaded in the active slot ("" if none).
std::string currentTrack() const;
// Fade playback control (used by the scroller page)
bool playTrackFadeIn(const std::string& wav_filename, float seconds);
bool playTrackCrossfade(const std::string& wav_filename, float seconds);
// Fades any playing track out over `seconds`. Returns false when nothing
// was playing, so callers can skip teardown delays tied to the fade.
bool stopTrackFadeOut(float seconds);
// Drive in-progress fade ramps; call once per frame.
void update(float dt);
private:
struct TrackSlot {
MIX_Track* track = nullptr;
MIX_Audio* audio = nullptr;
float fadeInDuration = 0.0f; // >0 while ramping in (seconds)
float fadeInElapsed = 0.0f;
float fadeOutRemaining = 0.0f; // >0 while fading out (seconds)
};
float effectiveGain() const;
bool loadTrackInto(int slotIndex, const std::string& wav_filename);
void startFadeIn(int slotIndex, float seconds);
config::ConfigManager* configManager_ = nullptr;
bool initialized_ = false;
bool enabled_ = true;
int volume_ = 80; // 0 - 100
std::string currentDevice_ = "";
std::string currentTrack_ = "";
MIX_Mixer* mixer_ = nullptr;
TrackSlot slots_[2];
int activeSlot_ = 0;
mutable std::mutex mutex_;
};
} // namespace radiantwave::audio