From 27416ab0cd8508324aa3d4fab8c5c5bd4b619275 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 14 Oct 2025 12:43:51 +0300 Subject: [PATCH] add audio::InputDevice --- src/audio/AL/ALAudio.cpp | 47 ++++++++++++++++++++++++++++++++++++++++ src/audio/AL/ALAudio.hpp | 25 +++++++++++++++++++++ src/audio/NoAudio.hpp | 7 ++++++ src/audio/audio.hpp | 17 +++++++++++++++ 4 files changed, 96 insertions(+) diff --git a/src/audio/AL/ALAudio.cpp b/src/audio/AL/ALAudio.cpp index 7f28882b..92dd209a 100644 --- a/src/audio/AL/ALAudio.cpp +++ b/src/audio/AL/ALAudio.cpp @@ -37,6 +37,38 @@ std::unique_ptr ALSound::newInstance(int priority, int channel) const { return speaker; } +ALInputDevice::ALInputDevice( + ALAudio* al, ALCdevice* device, uint channels, uint bitsPerSample +) + : al(al), device(device), channels(channels), bitsPerSample(bitsPerSample) { +} + +ALInputDevice::~ALInputDevice() { + alcCaptureCloseDevice(device); +} + +void ALInputDevice::startCapture() { + AL_CHECK(alcCaptureStart(device)); +} + +void ALInputDevice::stopCapture() { + AL_CHECK(alcCaptureStop(device)); +} + +uint ALInputDevice::getChannels() const { + return channels; +} + +size_t ALInputDevice::read(char* buffer, size_t bufferSize) { + ALCint samplesCount; + AL_CHECK(alcGetIntegerv(device, ALC_CAPTURE_SAMPLES, 1, &samplesCount)); + size_t samplesRead = std::min( + samplesCount, bufferSize / channels / (bitsPerSample >> 3) + ); + AL_CHECK(alcCaptureSamples(device, buffer, samplesRead)); + return samplesRead; +} + ALStream::ALStream( ALAudio* al, std::shared_ptr source, bool keepSource ) @@ -411,6 +443,21 @@ std::unique_ptr ALAudio::openStream( return std::make_unique(this, stream, keepSource); } +std::unique_ptr ALAudio::openInputDevice( + uint sampleRate, uint channels, uint bitsPerSample +) { + uint bps = bitsPerSample >> 3; + AL_CHECK( + ALCdevice* device = alcCaptureOpenDevice( + nullptr, + sampleRate, + AL::to_al_format(channels, bps), + sampleRate * channels * bps + ) + ); + return std::make_unique(this, device, channels, bps); +} + std::unique_ptr ALAudio::create() { ALCdevice* device = alcOpenDevice(nullptr); if (device == nullptr) return nullptr; diff --git a/src/audio/AL/ALAudio.hpp b/src/audio/AL/ALAudio.hpp index 7e0f0c29..d04d45b6 100644 --- a/src/audio/AL/ALAudio.hpp +++ b/src/audio/AL/ALAudio.hpp @@ -82,6 +82,26 @@ namespace audio { static inline constexpr uint STREAM_BUFFERS = 3; }; + class ALInputDevice : public InputDevice { + public: + ALInputDevice( + ALAudio* al, ALCdevice* device, uint channels, uint bitsPerSample + ); + ~ALInputDevice() override; + + void startCapture() override; + void stopCapture() override; + + uint getChannels() const override; + + size_t read(char* buffer, size_t bufferSize) override; + private: + ALAudio* al; + ALCdevice* device; + uint channels; + uint bitsPerSample; + }; + /// @brief AL source adapter class ALSpeaker : public Speaker { ALAudio* al; @@ -157,10 +177,15 @@ namespace audio { std::unique_ptr createSound( std::shared_ptr pcm, bool keepPCM ) override; + std::unique_ptr openStream( std::shared_ptr stream, bool keepSource ) override; + std::unique_ptr openInputDevice( + uint sampleRate, uint channels, uint bitsPerSample + ) override; + void setListener( glm::vec3 position, glm::vec3 velocity, diff --git a/src/audio/NoAudio.hpp b/src/audio/NoAudio.hpp index edfc3319..bc2e6b49 100644 --- a/src/audio/NoAudio.hpp +++ b/src/audio/NoAudio.hpp @@ -71,10 +71,17 @@ namespace audio { std::unique_ptr createSound( std::shared_ptr pcm, bool keepPCM ) override; + std::unique_ptr openStream( std::shared_ptr stream, bool keepSource ) override; + std::unique_ptr openInputDevice( + uint sampleRate, uint channels, uint bitsPerSample + ) override { + return nullptr; + } + void setListener( glm::vec3 position, glm::vec3 velocity, glm::vec3 at, glm::vec3 up ) override { diff --git a/src/audio/audio.hpp b/src/audio/audio.hpp index a3553b38..56de29ad 100644 --- a/src/audio/audio.hpp +++ b/src/audio/audio.hpp @@ -108,6 +108,20 @@ namespace audio { } }; + class InputDevice { + public: + virtual ~InputDevice() {}; + + virtual void startCapture() = 0; + virtual void stopCapture() = 0; + + /// @brief Get number of audio channels + /// @return 1 if mono, 2 if stereo + virtual uint getChannels() const = 0; + + virtual size_t read(char* buffer, size_t bufferSize) = 0; + }; + /// @brief audio::PCMStream is a data source for audio::Stream class PCMStream { public: @@ -345,6 +359,9 @@ namespace audio { virtual std::unique_ptr openStream( std::shared_ptr stream, bool keepSource ) = 0; + virtual std::unique_ptr openInputDevice( + uint sampleRate, uint channels, uint bitsPerSample + ) = 0; virtual void setListener( glm::vec3 position, glm::vec3 velocity,