Userspace: Add simple AudioServer and LibAudio
This commit is contained in:
64
userspace/libraries/LibAudio/include/LibAudio/Audio.h
Normal file
64
userspace/libraries/LibAudio/include/LibAudio/Audio.h
Normal 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 };
|
||||
};
|
||||
|
||||
}
|
||||
32
userspace/libraries/LibAudio/include/LibAudio/AudioLoader.h
Normal file
32
userspace/libraries/LibAudio/include/LibAudio/AudioLoader.h
Normal 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 };
|
||||
};
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user