summaryrefslogtreecommitdiff
path: root/plugin/src/Caelestia/audioprovider.hpp
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-09-07 15:15:10 +1000
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-09-07 15:15:10 +1000
commit2c5801237cfb4eb5686da43dcf6a5fff9baa1f62 (patch)
tree64bdbdbf051259586745fc8ae47c33e572ffb03b /plugin/src/Caelestia/audioprovider.hpp
parentplugin: async audio processing (diff)
downloadcaelestia-shell-2c5801237cfb4eb5686da43dcf6a5fff9baa1f62.tar.gz
caelestia-shell-2c5801237cfb4eb5686da43dcf6a5fff9baa1f62.tar.bz2
caelestia-shell-2c5801237cfb4eb5686da43dcf6a5fff9baa1f62.zip
plugin/ap: properly buffer data
Run at a stable fps instead of in large chunks Use one thread for collecting and another for processing
Diffstat (limited to 'plugin/src/Caelestia/audioprovider.hpp')
-rw-r--r--plugin/src/Caelestia/audioprovider.hpp74
1 files changed, 60 insertions, 14 deletions
diff --git a/plugin/src/Caelestia/audioprovider.hpp b/plugin/src/Caelestia/audioprovider.hpp
index 205be2c..2acdb2d 100644
--- a/plugin/src/Caelestia/audioprovider.hpp
+++ b/plugin/src/Caelestia/audioprovider.hpp
@@ -3,54 +3,100 @@
#include "service.hpp"
#include <QAudioSource>
#include <QIODevice>
+#include <QMutex>
#include <QObject>
+#include <QQueue>
#include <QThread>
+#include <QTimer>
+#include <QVector>
#include <qqmlintegration.h>
namespace caelestia {
-class AudioWorker : public QObject {
+class AudioProvider;
+
+class AudioCollector : public QObject {
Q_OBJECT
public:
- explicit AudioWorker(int sampleRate = 44100, int hopSize = 512, QObject* parent = nullptr);
- ~AudioWorker();
+ explicit AudioCollector(AudioProvider* provider, QObject* parent = nullptr);
+ ~AudioCollector();
void init();
-protected:
- int m_sampleRate;
- int m_hopSize;
-
- template <typename T> void process(T* outBuf);
-
private:
QAudioSource* m_source;
QIODevice* m_device;
+ AudioProvider* m_provider;
+ int m_sampleRate;
+ int m_chunkSize;
+
+ QVector<double> m_chunk;
+ int m_chunkOffset;
+
Q_INVOKABLE void start();
Q_INVOKABLE void stop();
void handleStateChanged(QtAudio::State state) const;
+ void loadChunk();
+};
+
+class AudioProcessor : public QObject {
+ Q_OBJECT
+
+public:
+ explicit AudioProcessor(AudioProvider* provider, QObject* parent = nullptr);
+ ~AudioProcessor();
+
+ void init();
- virtual void processData() = 0;
- virtual void consumeData() = 0;
+protected:
+ int m_sampleRate;
+ int m_chunkSize;
+
+private:
+ AudioProvider* m_provider;
+ QTimer* m_timer;
+
+ Q_INVOKABLE void start();
+ Q_INVOKABLE void stop();
+
+ void handleTimeout();
+ virtual void processChunk(const QVector<double>& chunk) = 0;
};
class AudioProvider : public Service {
Q_OBJECT
public:
- explicit AudioProvider(QObject* parent = nullptr);
+ explicit AudioProvider(int sampleRate = 44100, int chunkSize = 512, QObject* parent = nullptr);
~AudioProvider();
+ [[nodiscard]] int sampleRate() const;
+ [[nodiscard]] int chunkSize() const;
+
+ void withLock(std::function<void()> fn);
+
+ [[nodiscard]] bool hasChunks() const;
+ [[nodiscard]] QVector<double> nextChunk();
+ void loadChunk(QVector<double> chunk);
+
protected:
- AudioWorker* m_worker;
+ int m_sampleRate;
+ int m_chunkSize;
+
+ QMutex m_mutex;
+ QQueue<QVector<double>> m_chunks;
+
+ AudioCollector* m_collector;
+ AudioProcessor* m_processor;
void init();
private:
- QThread* m_thread;
+ QThread* m_collectorThread;
+ QThread* m_processorThread;
void start() override;
void stop() override;