From d0fdbefbfb60994ad8d6cf3b7129dcdd556c1924 Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Mon, 8 Sep 2025 21:10:30 +1000 Subject: plugin/ap: fix collector Actually read from speakers not mic --- plugin/src/Caelestia/audioprovider.cpp | 176 ++++----------------------------- 1 file changed, 20 insertions(+), 156 deletions(-) (limited to 'plugin/src/Caelestia/audioprovider.cpp') diff --git a/plugin/src/Caelestia/audioprovider.cpp b/plugin/src/Caelestia/audioprovider.cpp index becfb63..008e360 100644 --- a/plugin/src/Caelestia/audioprovider.cpp +++ b/plugin/src/Caelestia/audioprovider.cpp @@ -1,5 +1,6 @@ #include "audioprovider.hpp" +#include "audiocollector.hpp" #include "service.hpp" #include #include @@ -9,121 +10,27 @@ #include #include #include -#include -#include -#include -#include namespace caelestia { -AudioCollector::AudioCollector(AudioProvider* provider, QObject* parent) +AudioProcessor::AudioProcessor(QObject* parent) : QObject(parent) - , m_source(nullptr) - , m_device(nullptr) - , m_provider(provider) - , m_sampleRate(provider->sampleRate()) - , m_chunkSize(provider->chunkSize()) - , m_chunk(m_chunkSize) - , m_chunkOffset(0) {} - -AudioCollector::~AudioCollector() { - m_source->stop(); -} - -void AudioCollector::init() { - QAudioFormat format; - format.setSampleRate(m_sampleRate); - format.setChannelCount(1); - format.setSampleFormat(QAudioFormat::Int16); - - m_source = new QAudioSource(QMediaDevices::defaultAudioInput(), format, this); - connect(m_source, &QAudioSource::stateChanged, this, &AudioCollector::handleStateChanged); -}; - -void AudioCollector::start() { - if (!m_source) { - return; - } - - m_device = m_source->start(); - connect(m_device, &QIODevice::readyRead, this, &AudioCollector::loadChunk); -} - -void AudioCollector::stop() { - if (m_source) { - m_source->stop(); - m_device = nullptr; - } -} - -void AudioCollector::loadChunk() { - const QByteArray data = m_device->readAll(); - const int16_t* samples = reinterpret_cast(data.constData()); - const size_t count = static_cast(data.size()) / sizeof(int16_t); - - size_t i = 0; - while (i < count) { - const int spaceLeft = m_chunkSize - m_chunkOffset; - const auto toCopy = std::min(static_cast(spaceLeft), count - i); - - std::transform(samples + i, samples + i + toCopy, m_chunk.begin() + m_chunkOffset, [](int16_t sample) { - return sample / 32768.0; - }); - - m_chunkOffset += toCopy; - i += toCopy; - - if (m_chunkOffset == m_chunkSize) { - if (std::any_of(m_chunk.constBegin(), m_chunk.constEnd(), [](double d) { - return std::abs(d) > 1e-6; - })) { - m_provider->loadChunk(m_chunk); - } - m_chunkOffset = 0; - } - } -} - -void AudioCollector::handleStateChanged(QtAudio::State state) const { - if (state == QtAudio::StoppedState && m_source->error() != QtAudio::NoError) { - switch (m_source->error()) { - case QtAudio::OpenError: - qWarning() << "AudioWorker: failed to open audio device"; - break; - case QtAudio::IOError: - qWarning() << "AudioWorker: an error occurred during read/write of audio device"; - break; - case QtAudio::UnderrunError: - qWarning() << "AudioWorker: audio data is not being fed to audio device fast enough"; - break; - case QtAudio::FatalError: - qCritical() << "AudioWorker: fatal error in audio device"; - break; - default: - break; - } - } -} - -AudioProcessor::AudioProcessor(AudioProvider* provider, QObject* parent) - : QObject(parent) - , m_sampleRate(provider->sampleRate()) - , m_chunkSize(provider->chunkSize()) - , m_provider(provider) {} + , m_sampleRate(AudioCollector::instance()->sampleRate()) + , m_chunkSize(AudioCollector::instance()->chunkSize()) + , m_bufferSize(AudioCollector::instance()->bufferSize()) {} AudioProcessor::~AudioProcessor() { - if (m_timer) { - m_timer->stop(); - } + stop(); } void AudioProcessor::init() { m_timer = new QTimer(this); m_timer->setInterval(static_cast(m_chunkSize * 1000.0 / m_sampleRate)); - connect(m_timer, &QTimer::timeout, this, &AudioProcessor::handleTimeout); + connect(m_timer, &QTimer::timeout, this, &AudioProcessor::process); } void AudioProcessor::start() { + AudioCollector::instance()->ref(); if (m_timer) { m_timer->start(); } @@ -133,60 +40,19 @@ void AudioProcessor::stop() { if (m_timer) { m_timer->stop(); } + AudioCollector::instance()->unref(); } -void AudioProcessor::handleTimeout() { - const QVector chunk = m_provider->nextChunk(); - if (!chunk.isEmpty()) { - processChunk(chunk); - } -} - -AudioProvider::AudioProvider(int sampleRate, int chunkSize, QObject* parent) +AudioProvider::AudioProvider(QObject* parent) : Service(parent) - , m_sampleRate(sampleRate) - , m_chunkSize(chunkSize) - , m_collector(new AudioCollector(this)) , m_processor(nullptr) - , m_collectorThread(new QThread(this)) - , m_processorThread(nullptr) { - m_collector->moveToThread(m_collectorThread); - - connect(m_collectorThread, &QThread::started, m_collector, &AudioCollector::init); - connect(m_collectorThread, &QThread::finished, m_collector, &AudioCollector::deleteLater); - connect(m_collectorThread, &QThread::finished, m_collectorThread, &QThread::deleteLater); - - m_collectorThread->start(); -} + , m_thread(nullptr) {} AudioProvider::~AudioProvider() { - m_collectorThread->quit(); - if (m_processorThread) { - m_processorThread->quit(); - m_processorThread->wait(); + if (m_thread) { + m_thread->quit(); + m_thread->wait(); } - m_collectorThread->wait(); -} - -int AudioProvider::sampleRate() const { - return m_sampleRate; -} - -int AudioProvider::chunkSize() const { - return m_chunkSize; -} - -QVector AudioProvider::nextChunk() { - QMutexLocker lock(&m_mutex); - if (m_chunks.isEmpty()) { - return {}; - } - return m_chunks.dequeue(); -} - -void AudioProvider::loadChunk(const QVector& chunk) { - QMutexLocker lock(&m_mutex); - m_chunks.enqueue(chunk); } void AudioProvider::init() { @@ -195,25 +61,23 @@ void AudioProvider::init() { return; } - m_processorThread = new QThread(this); - m_processor->moveToThread(m_processorThread); + m_thread = new QThread(this); + m_processor->moveToThread(m_thread); - connect(m_processorThread, &QThread::started, m_processor, &AudioProcessor::init); - connect(m_processorThread, &QThread::finished, m_processor, &AudioProcessor::deleteLater); - connect(m_processorThread, &QThread::finished, m_processorThread, &QThread::deleteLater); + connect(m_thread, &QThread::started, m_processor, &AudioProcessor::init); + connect(m_thread, &QThread::finished, m_processor, &AudioProcessor::deleteLater); + connect(m_thread, &QThread::finished, m_thread, &QThread::deleteLater); - m_processorThread->start(); + m_thread->start(); } void AudioProvider::start() { - QMetaObject::invokeMethod(m_collector, "start", Qt::QueuedConnection); if (m_processor) { QMetaObject::invokeMethod(m_processor, "start", Qt::QueuedConnection); } } void AudioProvider::stop() { - QMetaObject::invokeMethod(m_collector, "stop", Qt::QueuedConnection); if (m_processor) { QMetaObject::invokeMethod(m_processor, "stop", Qt::QueuedConnection); } -- cgit v1.2.3-freya