From 9bd6dc956fceb591dcad7c94f5bbc824c9f83c21 Mon Sep 17 00:00:00 2001 From: josh Date: Fri, 18 Jul 2025 12:25:25 -0500 Subject: [PATCH] WIP Edits --- CMakeLists.txt | 6 +- include/ReMixer/IAudioDevice.hpp | 16 +++ .../{PulseSubsystem.h => PulseDevice.h} | 14 ++ include/ReMixer/ReMixer.h | 131 +++--------------- include/ReMixer/Sound.hpp | 2 + include/ReMixer/WasapiDevice.hpp | 8 ++ main.cpp | 5 +- .../{PulseSubsystem.cpp => PulseDevice.cpp} | 2 +- 8 files changed, 65 insertions(+), 119 deletions(-) rename include/ReMixer/{PulseSubsystem.h => PulseDevice.h} (93%) create mode 100644 include/ReMixer/WasapiDevice.hpp rename src/linux/{PulseSubsystem.cpp => PulseDevice.cpp} (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt index ec0845c..d14ae20 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,9 +38,7 @@ endif() include_directories("include") -add_library(ReMixer ${SOURCES} - src/linux/PulseSubsystem.cpp - src/linux/SoundSubsystem.cpp) +add_library(ReMixer ${SOURCES}) add_executable(ReMixer-Test main.cpp) @@ -65,7 +63,7 @@ target_link_libraries(ReMixer-Test PUBLIC ReMixer) add_executable(pacat pacat_simple.cpp src/windows/ReMixer.cpp - include/ReMixer/PulseSubsystem.h) + include/ReMixer/PulseDevice.h) target_link_libraries(pacat pulse-simple pulse) add_executable(vorbis_decode vorbis_decode.cpp) diff --git a/include/ReMixer/IAudioDevice.hpp b/include/ReMixer/IAudioDevice.hpp index 1f633b9..d9b653e 100644 --- a/include/ReMixer/IAudioDevice.hpp +++ b/include/ReMixer/IAudioDevice.hpp @@ -1,4 +1,5 @@ #pragma once +#include "AudioFormat.hpp" #include "ReMixer.h" namespace ReMixer { @@ -15,6 +16,12 @@ namespace ReMixer { std::set supported_formats; }; + class IAudioDevice; + + using PlaybackCallback = std::; + using CaptureCallback = 0; + using DeviceStateCallback = 0; + class IAudioDevice { public: virtual ~IAudioDevice() = default; @@ -25,6 +32,15 @@ namespace ReMixer { virtual bool Stop() = 0; virtual bool IsRunning() const = 0; + virtual AudioDeviceInfo GetInfo() const = 0; + virtual AudioFormat GetActualFormat() const = 0; + virtual uint32_t GetActualBufferSizeFrames() const = 0; + virtual double GetLatencyMilliseconds() const = 0; + + + template + T* AsPlatformSpecific() { return dynamic_cast(*this); } + }; } diff --git a/include/ReMixer/PulseSubsystem.h b/include/ReMixer/PulseDevice.h similarity index 93% rename from include/ReMixer/PulseSubsystem.h rename to include/ReMixer/PulseDevice.h index f12429b..c6a20d8 100644 --- a/include/ReMixer/PulseSubsystem.h +++ b/include/ReMixer/PulseDevice.h @@ -25,6 +25,20 @@ namespace ReMixer { + namespace PulseAudio { + class PulseDevice : public IAudioDevice { + public: + PulseDevice(const AudioDeviceInfo& info); + ~PulseDevice() override; + + + + + }; + } + + + /// A PulseAudio implementation of the SoundSubsystem. class PulseAudioSubsystem : public SoundSubsystem { diff --git a/include/ReMixer/ReMixer.h b/include/ReMixer/ReMixer.h index 2da93da..98ee867 100644 --- a/include/ReMixer/ReMixer.h +++ b/include/ReMixer/ReMixer.h @@ -7,137 +7,42 @@ namespace ReMixer { - /// 1. Abstraction Layer: - /// Define abstract base classes or interfaces that capture the common - /// functionalities across all supported audio APIs. - /// 2. Platform Specific Implementations: - /// Create conrete classes for each platform (PulseDevice, WasapiDevice) - /// that inherit from the abstract interfaces and implement the API-specific calls. - /// 3. Factory Pattern: - /// Use a factory function or class to create the correct platform-specific - /// implementation at runtime, based on the operating system. - /// 4. Resource Management: - /// Employ RAII for managing audio device handles, streams, and buffers. Utilize Smart Pointers? - /// 5. Callbacks for asynchronous operations: - /// Most low-level audio APIs use callbacks for delivering audio data (playback/capture) - /// or notifying of device state changes. Your wrapper classes should expose this through - /// C++ lambdas or std::function (or josh/Event) - /// 6. Error Handling: - /// A consistent error reporting mechanism is crucial - /// 7. Data Formats: - /// Handle common audio formats (PCM float, int16, int32) and sample rates. Provide conversion utilities if necessary. - /// 8. Device Enumeration: - /// Allow users to discover available audio input and output devices. - /// - - enum class SampleFormat { - Unknown, - Float16, - Float32, - Int16, - Int32, - }; - - unsigned operator ""_Hz(unsigned long long int frequency); - unsigned operator ""_kHz(long double frequency); - unsigned operator ""_kHz(unsigned long long int frequency); - - struct AudioFormat { - uint32_t sample_rate; - uint16_t channels; - SampleFormat format; - - static AudioFormat StereoFloat(uint32_t rate) { - return {rate, 2, SampleFormat::Float16}; - } - - static AudioFormat StereoFloat48kHz() { - return StereoFloat(48_kHz); - } - }; + /// TODO: Support JACK + /// TOOD: Support ALSA + /// TODO: Support PulseAudio + /// TODO: Support WASAPI - enum class DeviceType { - Unknown, Output, Input, Duplex - }; + // TODO: Support Recording - struct AudioDeviceInfo { - std::string id; - std::string name; - DeviceType type; - bool is_default; - std::set supported_formats; - }; class Sound; + class SoundHandle; + + class IAudioDevice; + class Stream; class SoundSubsystem; class PulseAudioSubsystem; class PulseStream; - enum class PlaybackStatus { Stopped, Playing, Paused, Finished, Error }; - - class SoundHandle { - friend void Init(); - friend SoundHandle* PlaySoundAsync(Sound& sound); - public: - - Event<> Finished; - Event<> Paused; - Event ErrorEncountered; - - - void Pause(); - void Resume(); - void Stop(); - - PlaybackStatus Status() const; - bool IsPlaying() const; - bool IsPaused() const; - bool IsStopped(); - float GetPlaybackPositionMs() const; - float GetPlaybackPositionPercent() const; - - /// Playback speed control (e.g., 0.5 for half speed, 2.0 for double speed) - /// @note Requires sample rate conversion or similar at lower level. - void SetPlaybackSpeed(float rate); - float GetPlaybackSpeed() const; - - void SetPlaybackPositionMs(float ms); - void SetPlaybackPositionPercent(float percent); - void Seek(float ms); - void SeekPercent(float percent); - - /// Volume control (0.0 to 1.0) - void SetVolume(float volume); - float GetVolume() const; - protected: - SoundHandle(const Sound& sound); - - private: - }; - - class IAudioDevice { - public: - virtual ~IAudioDevice() = default; - - virtual bool Initialize(const AudioFormat& requestedFormat, uint32_t bufferSizeFrames) = 0; - virtual void Shutdown() = 0; - virtual bool Start() = 0; - virtual bool Stop() = 0; - virtual bool IsRunning() const = 0; - - - }; - void Init(); void Cleanup(); +#pragma region Simple API /// Simple high-level API for sound playback. /// @note Assumes you want the default device, and ideal parameters to properly play the sound. /// @return SoundHandle instance for managing the state of playback. (i.e. pause, seek, resume, playback speed, events.) SoundHandle* PlaySoundAsync(Sound& Sound); + std::vector EnumerateDevices(); +#pragma endregion + +#pragma region Advanced API + + +#pragma endregion + } diff --git a/include/ReMixer/Sound.hpp b/include/ReMixer/Sound.hpp index 6f4e545..2732307 100644 --- a/include/ReMixer/Sound.hpp +++ b/include/ReMixer/Sound.hpp @@ -20,6 +20,8 @@ #include #include +#include "AudioFormat.hpp" + int mix(int a, int b); namespace ReMixer { diff --git a/include/ReMixer/WasapiDevice.hpp b/include/ReMixer/WasapiDevice.hpp new file mode 100644 index 0000000..a0fdd3f --- /dev/null +++ b/include/ReMixer/WasapiDevice.hpp @@ -0,0 +1,8 @@ +// +// Created by josh on 7/16/25. +// + +#ifndef WASAPIDEVICE_HPP +#define WASAPIDEVICE_HPP + +#endif //WASAPIDEVICE_HPP diff --git a/main.cpp b/main.cpp index 9dcc188..9f83627 100644 --- a/main.cpp +++ b/main.cpp @@ -16,13 +16,16 @@ #include #include #include -#include +#include #include +#include "ReMixer/Frequency.hpp" + [[noreturn]] int main() { using namespace ReMixer; using namespace std::chrono_literals; + using namespace ReMixer::FrequencyLiterals; uint measurement = 44.1_kHz; diff --git a/src/linux/PulseSubsystem.cpp b/src/linux/PulseDevice.cpp similarity index 99% rename from src/linux/PulseSubsystem.cpp rename to src/linux/PulseDevice.cpp index 3a59d0d..1809ba5 100644 --- a/src/linux/PulseSubsystem.cpp +++ b/src/linux/PulseDevice.cpp @@ -1,4 +1,4 @@ -#include +#include void ReMixer::PulseAudioSubsystem::Play(ReMixer::PulseStream &stream, const ReMixer::Sound &sound) {