summaryrefslogtreecommitdiff
path: root/plugin/src/Caelestia/beattracker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/src/Caelestia/beattracker.cpp')
-rw-r--r--plugin/src/Caelestia/beattracker.cpp110
1 files changed, 25 insertions, 85 deletions
diff --git a/plugin/src/Caelestia/beattracker.cpp b/plugin/src/Caelestia/beattracker.cpp
index 433ffab..a23d052 100644
--- a/plugin/src/Caelestia/beattracker.cpp
+++ b/plugin/src/Caelestia/beattracker.cpp
@@ -1,109 +1,49 @@
#include "beattracker.hpp"
-#include <QAudioSource>
-#include <QDebug>
-#include <QIODevice>
-#include <QMediaDevices>
-#include <QObject>
+#include "audiocollector.hpp"
+#include "audioprovider.hpp"
#include <aubio/aubio.h>
namespace caelestia {
-BeatTracker::BeatTracker(uint_t sampleRate, uint_t hopSize, QObject* parent)
- : QObject(parent)
- , m_tempo(new_aubio_tempo("default", 1024, hopSize, sampleRate))
- , m_in(new_fvec(hopSize))
- , m_out(new_fvec(2))
- , m_hopSize(hopSize)
- , m_bpm(120)
- , m_refCount(0) {
- QAudioFormat format;
- format.setSampleRate(static_cast<int>(sampleRate));
- format.setChannelCount(1);
- format.setSampleFormat(QAudioFormat::Int16);
+BeatProcessor::BeatProcessor(QObject* parent)
+ : AudioProcessor(parent)
+ , m_tempo(new_aubio_tempo("default", 1024, m_chunkSize, m_sampleRate))
+ , m_in(new_fvec(m_chunkSize))
+ , m_out(new_fvec(2)) {};
- m_source = new QAudioSource(QMediaDevices::defaultAudioInput(), format, this);
- connect(m_source, &QAudioSource::stateChanged, this, &BeatTracker::handleStateChanged);
-};
-
-BeatTracker::~BeatTracker() {
+BeatProcessor::~BeatProcessor() {
del_aubio_tempo(m_tempo);
del_fvec(m_in);
del_fvec(m_out);
-
- m_source->stop();
- delete m_source;
-}
-
-smpl_t BeatTracker::bpm() const {
- return m_bpm;
}
-int BeatTracker::refCount() const {
- return m_refCount;
-}
+void BeatProcessor::process() {
+ AudioCollector::instance()->readChunk(m_in->data, m_chunkSize);
-void BeatTracker::setRefCount(int refCount) {
- if (m_refCount == refCount) {
- return;
- }
-
- m_refCount = refCount;
- emit refCountChanged();
-
- if (m_refCount == 0) {
- stop();
- } else if (!m_device) {
- start();
+ aubio_tempo_do(m_tempo, m_in, m_out);
+ if (m_out->data[0] != 0.0f) {
+ emit beat(aubio_tempo_get_bpm(m_tempo));
}
}
-void BeatTracker::start() {
- m_device = m_source->start();
- connect(m_device, &QIODevice::readyRead, this, &BeatTracker::process);
-}
+BeatTracker::BeatTracker(QObject* parent)
+ : AudioProvider(parent)
+ , m_bpm(120) {
+ m_processor = new BeatProcessor();
+ init();
-void BeatTracker::stop() {
- m_source->stop();
- m_device = nullptr;
+ connect(static_cast<BeatProcessor*>(m_processor), &BeatProcessor::beat, this, &BeatTracker::updateBpm);
}
-void BeatTracker::process() {
- const QByteArray data = m_device->readAll();
- const int16_t* samples = reinterpret_cast<const int16_t*>(data.constData());
- const size_t count = static_cast<size_t>(data.size()) / sizeof(int16_t);
-
- for (size_t i = 0; i < count; ++i) {
- m_in->data[i % m_hopSize] = samples[i] / 32768.0f;
- if ((i + 1) % m_hopSize == 0) {
- aubio_tempo_do(m_tempo, m_in, m_out);
- if (m_out->data[0] != 0.0f) {
- m_bpm = aubio_tempo_get_bpm(m_tempo);
- emit bpmChanged();
- emit beat(m_bpm);
- }
- }
- }
+smpl_t BeatTracker::bpm() const {
+ return m_bpm;
}
-void BeatTracker::handleStateChanged(QtAudio::State state) const {
- if (state == QtAudio::StoppedState && m_source->error() != QtAudio::NoError) {
- switch (m_source->error()) {
- case QtAudio::OpenError:
- qWarning() << "BeatTracker: failed to open audio device";
- break;
- case QtAudio::IOError:
- qWarning() << "BeatTracker: an error occurred during read/write of audio device";
- break;
- case QtAudio::UnderrunError:
- qWarning() << "BeatTracker: audio data is not being fed to audio device fast enough";
- break;
- case QtAudio::FatalError:
- qCritical() << "BeatTracker: fatal error in audio device";
- break;
- default:
- break;
- }
+void BeatTracker::updateBpm(smpl_t bpm) {
+ if (!qFuzzyCompare(bpm + 1.0f, m_bpm + 1.0f)) {
+ m_bpm = bpm;
+ emit bpmChanged();
}
}