diff options
Diffstat (limited to 'plugin')
| -rw-r--r-- | plugin/src/Caelestia/audiocollector.cpp | 80 | ||||
| -rw-r--r-- | plugin/src/Caelestia/audiocollector.hpp | 14 | ||||
| -rw-r--r-- | plugin/src/Caelestia/audioprovider.cpp | 8 | ||||
| -rw-r--r-- | plugin/src/Caelestia/audioprovider.hpp | 6 |
4 files changed, 36 insertions, 72 deletions
diff --git a/plugin/src/Caelestia/audiocollector.cpp b/plugin/src/Caelestia/audiocollector.cpp index cf3a673..036a383 100644 --- a/plugin/src/Caelestia/audiocollector.cpp +++ b/plugin/src/Caelestia/audiocollector.cpp @@ -2,12 +2,10 @@ #include "service.hpp" #include <QDebug> -#include <QVector> #include <algorithm> #include <cstdint> #include <mutex> #include <pipewire/pipewire.h> -#include <qmutex.h> #include <spa/param/audio/format-utils.h> #include <spa/param/latency-utils.h> #include <stop_token> @@ -157,13 +155,14 @@ unsigned int PipeWireWorker::nextPowerOf2(unsigned int n) { return n; } -AudioCollector::AudioCollector(uint32_t sampleRate, uint32_t chunkSize, uint32_t bufferSize, QObject* parent) +AudioCollector::AudioCollector(uint32_t sampleRate, uint32_t chunkSize, QObject* parent) : Service(parent) - , m_buffer(bufferSize, 0.0f) - , m_bufferIndex(bufferSize) + , m_buffer1(chunkSize) + , m_buffer2(chunkSize) + , m_readBuffer(&m_buffer1) + , m_writeBuffer(&m_buffer2) , m_sampleRate(sampleRate) - , m_chunkSize(chunkSize) - , m_bufferSize(bufferSize) {} + , m_chunkSize(chunkSize) {} AudioCollector::~AudioCollector() { stop(); @@ -185,72 +184,49 @@ uint32_t AudioCollector::chunkSize() const { return m_chunkSize; } -uint32_t AudioCollector::bufferSize() const { - return m_bufferSize; -} - void AudioCollector::clearBuffer() { - std::lock_guard<std::mutex> lock(m_bufferMutex); - std::fill(m_buffer.begin(), m_buffer.end(), 0.0f); - m_bufferIndex = m_bufferSize; + auto* writeBuffer = m_writeBuffer.load(std::memory_order_relaxed); + std::fill(writeBuffer->begin(), writeBuffer->end(), 0.0f); + + auto* oldRead = m_readBuffer.exchange(writeBuffer, std::memory_order_acq_rel); + m_writeBuffer.store(oldRead, std::memory_order_release); } void AudioCollector::loadChunk(const int16_t* samples, uint32_t count) { - std::lock_guard<std::mutex> lock(m_bufferMutex); - - while (count > 0) { - const auto spaceToEnd = m_bufferSize - m_bufferIndex; - const auto toCopy = (count < spaceToEnd) ? count : spaceToEnd; + if (count > m_chunkSize) { + count = m_chunkSize; + } - std::transform(samples, samples + toCopy, m_buffer.begin() + m_bufferIndex, [](int16_t sample) { - return sample / 32768.0f; - }); + auto* writeBuffer = m_writeBuffer.load(std::memory_order_relaxed); + std::transform(samples, samples + count, writeBuffer->begin(), [](int16_t sample) { + return sample / 32768.0f; + }); - m_bufferIndex = (m_bufferIndex + toCopy) % m_bufferSize; - samples += toCopy; - count -= toCopy; - } + auto* oldRead = m_readBuffer.exchange(writeBuffer, std::memory_order_acq_rel); + m_writeBuffer.store(oldRead, std::memory_order_release); } uint32_t AudioCollector::readChunk(float* out, uint32_t count) { - std::lock_guard<std::mutex> lock(m_bufferMutex); - - if (count == 0 || count > m_bufferSize) { - count = m_bufferSize; + if (count == 0 || count > m_chunkSize) { + count = m_chunkSize; } - const auto start = (m_bufferIndex + m_bufferSize - count) % m_bufferSize; - const auto firstChunk = std::min(count, m_bufferSize - start); - - std::copy(m_buffer.begin() + start, m_buffer.begin() + start + firstChunk, out); - - if (firstChunk < count) { - std::copy(m_buffer.begin(), m_buffer.begin() + (count - firstChunk), out + firstChunk); - } + auto* readBuffer = m_readBuffer.load(std::memory_order_acquire); + std::memcpy(out, readBuffer->data(), count * sizeof(float)); return count; } uint32_t AudioCollector::readChunk(double* out, uint32_t count) { - std::lock_guard<std::mutex> lock(m_bufferMutex); - - if (count == 0 || count > m_bufferSize) { - count = m_bufferSize; + if (count == 0 || count > m_chunkSize) { + count = m_chunkSize; } - const auto start = (m_bufferIndex + m_bufferSize - count) % m_bufferSize; - const auto firstChunk = std::min(count, m_bufferSize - start); - - std::transform(m_buffer.begin() + start, m_buffer.begin() + start + firstChunk, out, [](float sample) { + auto* readBuffer = m_readBuffer.load(std::memory_order_acquire); + std::transform(readBuffer->begin(), readBuffer->begin() + count, out, [](float sample) { return static_cast<double>(sample); }); - if (firstChunk < count) { - std::transform(m_buffer.begin(), m_buffer.begin() + (count - firstChunk), out + firstChunk, [](float sample) { - return static_cast<double>(sample); - }); - } - return count; } diff --git a/plugin/src/Caelestia/audiocollector.hpp b/plugin/src/Caelestia/audiocollector.hpp index d60736f..420452c 100644 --- a/plugin/src/Caelestia/audiocollector.hpp +++ b/plugin/src/Caelestia/audiocollector.hpp @@ -2,6 +2,7 @@ #include "service.hpp" #include <QObject> +#include <atomic> #include <cstdint> #include <mutex> #include <pipewire/pipewire.h> @@ -43,15 +44,13 @@ class AudioCollector : public Service { Q_OBJECT public: - explicit AudioCollector( - uint32_t sampleRate = 44100, uint32_t chunkSize = 512, uint32_t bufferSize = 512, QObject* parent = nullptr); + explicit AudioCollector(uint32_t sampleRate = 44100, uint32_t chunkSize = 512, QObject* parent = nullptr); ~AudioCollector(); static AudioCollector* instance(); [[nodiscard]] uint32_t sampleRate() const; [[nodiscard]] uint32_t chunkSize() const; - [[nodiscard]] uint32_t bufferSize() const; void clearBuffer(); void loadChunk(const int16_t* samples, uint32_t count); @@ -63,13 +62,14 @@ private: inline static std::mutex s_mutex; std::jthread m_thread; - std::vector<float> m_buffer; - uint32_t m_bufferIndex; - std::mutex m_bufferMutex; + std::vector<float> m_buffer1; + std::vector<float> m_buffer2; + std::atomic<std::vector<float>*> m_readBuffer; + std::atomic<std::vector<float>*> m_writeBuffer; + uint32_t m_sampleCount; const uint32_t m_sampleRate; const uint32_t m_chunkSize; - const uint32_t m_bufferSize; void start() override; void stop() override; diff --git a/plugin/src/Caelestia/audioprovider.cpp b/plugin/src/Caelestia/audioprovider.cpp index 008e360..1b0eed3 100644 --- a/plugin/src/Caelestia/audioprovider.cpp +++ b/plugin/src/Caelestia/audioprovider.cpp @@ -2,22 +2,16 @@ #include "audiocollector.hpp" #include "service.hpp" -#include <QAudioSource> #include <QDebug> -#include <QIODevice> -#include <QMediaDevices> -#include <QMutexLocker> #include <QObject> #include <QThread> -#include <QVector> namespace caelestia { AudioProcessor::AudioProcessor(QObject* parent) : QObject(parent) , m_sampleRate(AudioCollector::instance()->sampleRate()) - , m_chunkSize(AudioCollector::instance()->chunkSize()) - , m_bufferSize(AudioCollector::instance()->bufferSize()) {} + , m_chunkSize(AudioCollector::instance()->chunkSize()) {} AudioProcessor::~AudioProcessor() { stop(); diff --git a/plugin/src/Caelestia/audioprovider.hpp b/plugin/src/Caelestia/audioprovider.hpp index 51ee930..1edefff 100644 --- a/plugin/src/Caelestia/audioprovider.hpp +++ b/plugin/src/Caelestia/audioprovider.hpp @@ -1,14 +1,9 @@ #pragma once #include "service.hpp" -#include <QAudioSource> -#include <QIODevice> -#include <QMutex> #include <QObject> -#include <QQueue> #include <QThread> #include <QTimer> -#include <QVector> #include <cstdint> #include <qqmlintegration.h> @@ -26,7 +21,6 @@ public: protected: uint32_t m_sampleRate; uint32_t m_chunkSize; - uint32_t m_bufferSize; private: QTimer* m_timer; |