Compare commits

...

2 Commits

Author SHA1 Message Date
09ee0360dc Merge remote-tracking branch 'origin/main'
# Conflicts:
#	main.cpp
2025-07-15 13:37:09 -05:00
9720989d34 Note taking, 2025-07-15 13:36:45 -05:00
3 changed files with 100 additions and 6 deletions

View File

@@ -1,6 +1,61 @@
#pragma once
#include <cstdint>
#include <set>
#include <string>
#include "sound.h"
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);
}
};
enum class StreamDirection {
PLAYBACK,
RECORD,
@@ -13,16 +68,51 @@ namespace ReMixer {
STEREO = true
};
unsigned operator ""_Hz(unsigned long long int frequency);
unsigned operator ""_kHz(long double frequency);
enum class DeviceType {
Unknown, Output, Input, Duplex
};
struct AudioDeviceInfo {
std::string id;
std::string name;
DeviceType type;
bool is_default;
std::set<AudioFormat> supported_formats;
};
class Stream;
class SoundSubsystem;
class PulseAudioSubsystem;
class PulseStream;
class SoundHandle {
public:
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();
/// 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);
}

View File

@@ -35,9 +35,13 @@
<< "default source" << info->default_source_name << std::endl;
};
PulseStream test_stream = server.CreateStream("Test Stream");
PulseStream second_stream = server.CreateStream("Second Stream");
//PulseStream test_stream2 = test.CreateStream("Another Test Stream");
//Sound test_sound = Sound::FromPCMFile("output.raw");
Sound test_sound = Sound::FromOGGVorbisFile("../test-sounds/wind.ogg");
Sound wav_sound = Sound::FromWAVFile("../test-sounds/robodeath.wav");
@@ -66,10 +70,6 @@
server.Play(test_stream, wav_sound);
while (true) {
std::this_thread::sleep_for(25ms);
}

View File

@@ -8,3 +8,7 @@ unsigned ReMixer::operator ""_Hz(unsigned long long int frequency) {
unsigned ReMixer::operator ""_kHz(long double frequency) {
return frequency * 1000;
}
unsigned ReMixer::operator ""_kHz(unsigned long long int frequency) {
return operator ""_kHz((long double)frequency);
}