112 lines
3.4 KiB
C++
112 lines
3.4 KiB
C++
/// ReMixer
|
|
/// A Public Domain C++ Audio Playback Library
|
|
/// By william @ RedactedSoftware. Thanks to Dawsh & Maxine.
|
|
/// (c) 2024 Redacted Software
|
|
/// This work is explicitly dedicated to the public domain, for the hopeful betterment of the software industry.
|
|
|
|
/// @file IStream.hpp
|
|
/// @desc An audio stream class that interfaces with pulseaudio, etc, to play back sounds.
|
|
/// @edit 2024-08-06
|
|
|
|
#pragma once
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <pulse/stream.h>
|
|
#include <pulse/thread-mainloop.h>
|
|
#include <iostream>
|
|
#include <ReMixer/Sound.hpp>
|
|
#include <ReMixer/SoundSubsystem.h>
|
|
|
|
namespace ReMixer {
|
|
|
|
enum class StreamDirection {
|
|
PLAYBACK,
|
|
RECORD,
|
|
};
|
|
|
|
/// We do not plan to support specifications such as 7.1 Surround.
|
|
/// 3D Positional Audio will be implemented later in software.
|
|
enum class StreamMode : bool {
|
|
MONO = false,
|
|
STEREO = true
|
|
};
|
|
|
|
|
|
/// Represents an audio data pathway (e.g. a playback stream, a capture stream).
|
|
/// It's responsible for managing the actual flow of audio data to or from the device,
|
|
/// handling buffers, and callbacks. An IAudioDevice will create and manage IStream instances.
|
|
/// @see IAudioDevice.
|
|
class IStream {
|
|
public:
|
|
virtual ~IStream() = default;
|
|
|
|
virtual bool Initialize() = 0;
|
|
virtual void Shutdown() = 0;
|
|
virtual bool IsInitialized() const = 0;
|
|
|
|
virtual bool Start() = 0;
|
|
virtual bool Stop() = 0;
|
|
virtual bool IsRunning() const = 0;
|
|
|
|
virtual void SetPlaybackCallback(PlaybackCallback callback, void* userData = nullptr) = 0;
|
|
virtual void SetCaptureCallback(CaptureCallback callback, void* userData = nullptr) = 0;
|
|
};
|
|
|
|
/// The stream class is an abstract class that represents distinct output / input channels on an audio system.
|
|
/// Each audio system implements their concept of streams as a derivation of this class.
|
|
class Stream {
|
|
public:
|
|
Stream() = default;
|
|
//Stream(SoundSubsystem* parent_system);
|
|
|
|
uint SampleRate() const { return sample_rate;}
|
|
uint ChannelCount() const { return channel_count;}
|
|
std::string Name() const { return name;}
|
|
|
|
/// TODO: It may not be possible to actually change these parameters after creation of the stream object.
|
|
void SetStreamDirection(const StreamDirection& direction);
|
|
void SetName(const std::string& name);
|
|
virtual void SetSampleRate(uint sample_rate);
|
|
void SetChannelCount(uint channel_count);
|
|
|
|
public:
|
|
unsigned int sample_rate;
|
|
size_t bufferSize;
|
|
uint16_t handle;
|
|
|
|
private:
|
|
std::string name;
|
|
std::string parent_name;
|
|
unsigned int channel_count;
|
|
StreamDirection dir;
|
|
std::vector<char> buffer;
|
|
unsigned int stream_id;
|
|
SoundSubsystem* parent_system;
|
|
};
|
|
|
|
class PulseStream : public Stream
|
|
{
|
|
public:
|
|
PulseStream() = default;
|
|
|
|
// PulseStream(PulseAudioSubsystem* parent_system) : Stream(parent_system) { }
|
|
|
|
void SetSampleRate(uint sample_rate) override;
|
|
|
|
pa_stream* stream;
|
|
|
|
static void OnStreamSuccess(pa_stream* s, int success, void* userdata);
|
|
static void OnStreamStateChanged(pa_stream* s, void* userdata);
|
|
static void OnStreamRequest(pa_stream* s, size_t length, void* userdata);
|
|
static void OnLatencyUpdate(pa_stream* s, void* userdata);
|
|
protected:
|
|
|
|
private:
|
|
|
|
};
|
|
}
|
|
|
|
|
|
|