Userspace: Add simple AudioServer and LibAudio

This commit is contained in:
2025-07-10 17:30:41 +03:00
parent 85d195212a
commit 3aea2c007d
13 changed files with 941 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
#pragma once
#include <BAN/Atomic.h>
#include <BAN/StringView.h>
#include <BAN/Vector.h>
#include <LibAudio/AudioLoader.h>
namespace LibAudio
{
static constexpr BAN::StringView s_audio_server_socket = "/tmp/audio-server.socket"_sv;
struct AudioBuffer
{
using sample_t = double;
uint32_t sample_rate;
uint32_t channels;
uint32_t capacity;
BAN::Atomic<uint32_t> tail { 0 };
BAN::Atomic<uint32_t> head { 0 };
sample_t samples[/* capacity */];
};
class Audio
{
BAN_NON_COPYABLE(Audio);
public:
static BAN::ErrorOr<Audio> load(BAN::StringView path);
static BAN::ErrorOr<Audio> random(uint32_t samples);
~Audio() { clear(); }
Audio(Audio&& other) { *this = BAN::move(other); }
Audio& operator=(Audio&& other);
BAN::ErrorOr<void> start();
bool is_playing() const { return m_audio_buffer->tail != m_audio_buffer->head; }
void update();
private:
Audio() = default;
Audio(BAN::UniqPtr<AudioLoader>&& audio_loader)
: m_audio_loader(BAN::move(audio_loader))
{ }
void clear();
BAN::ErrorOr<void> initialize(uint32_t total_samples);
private:
int m_server_fd { -1 };
BAN::UniqPtr<AudioLoader> m_audio_loader;
long m_smo_key { -1 };
size_t m_smo_size { 0 };
AudioBuffer* m_audio_buffer { nullptr };
};
}

View File

@@ -0,0 +1,32 @@
#pragma once
#include <BAN/StringView.h>
#include <BAN/UniqPtr.h>
namespace LibAudio
{
class AudioLoader
{
BAN_NON_COPYABLE(AudioLoader);
BAN_NON_MOVABLE(AudioLoader);
public:
static BAN::ErrorOr<BAN::UniqPtr<AudioLoader>> load(BAN::StringView path);
virtual ~AudioLoader();
virtual uint32_t channels() const = 0;
virtual uint32_t sample_rate() const = 0;
virtual uint32_t samples_remaining() const = 0;
virtual double get_sample() = 0;
protected:
AudioLoader() = default;
private:
void* m_mmap_addr { nullptr };
size_t m_mmap_size { 0 };
};
}

View File

@@ -0,0 +1,40 @@
#pragma once
#include <LibAudio/AudioLoader.h>
#include <BAN/ByteSpan.h>
namespace LibAudio
{
class WAVAudioLoader : public AudioLoader
{
public:
enum FormatCode : uint16_t
{
WAVE_FORMAT_PCM = 0x01,
WAVE_FORMAT_IEEE_FLOAT = 0x03,
};
public:
static bool can_load_from(BAN::ConstByteSpan data);
static BAN::ErrorOr<BAN::UniqPtr<AudioLoader>> create(BAN::ConstByteSpan data);
uint32_t channels() const override { return m_channels; }
uint32_t sample_rate() const override { return m_sample_rate; }
uint32_t samples_remaining() const override { return m_total_samples - m_current_sample; }
double get_sample() override;
private:
uint32_t m_channels { 0 };
uint32_t m_sample_rate { 0 };
uint32_t m_total_samples { 0 };
FormatCode m_sample_format;
uint16_t m_bits_per_sample { 0 };
size_t m_current_sample { 0 };
BAN::ConstByteSpan m_sample_data;
};
}