Files
ReMixer/include/ReMixer/IStream.hpp
2025-07-22 13:59:00 -05:00

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:
};
}