Files
AramJonghu 467e44bb9f
C++ / build (pull_request) Failing after 15s
Lint & Format (JS/TS) / lint-format (pull_request) Successful in 28s
Python / lint-format (pull_request) Successful in 45s
Python / test (pull_request) Successful in 38s
Lint & Format (Rust) / lint-format (pull_request) Successful in 1m45s
tidy&format(all): all files formatted and relevant warnings resolved
2026-06-30 02:04:24 +02:00

153 lines
2.9 KiB
C++

#include "cavaprovider.hpp"
#include "audiocollector.hpp"
#include "audioprovider.hpp"
#include <cava/cavacore.h>
#include <cstddef>
#include <qdebug.h>
namespace ZShell::services {
CavaProcessor::CavaProcessor(QObject* parent)
: AudioProcessor(parent)
, m_plan(nullptr)
, m_in(new double[ac::CHUNK_SIZE])
, m_out(nullptr)
, m_bars(0) {};
CavaProcessor::~CavaProcessor() {
cleanup();
delete[] m_in;
}
void CavaProcessor::process() {
if (!m_plan || m_bars == 0 || !m_out) {
return;
}
const int count =
static_cast<int>(AudioCollector::instance().readChunk(m_in));
// Process in data via cava
cava_execute(m_in, count, m_out, m_plan);
// Apply monstercat filter
QVector<double> values(m_bars);
for (int i = 0; i < m_bars; ++i) {
values[i] = m_out[i];
}
// Left to right pass
// const double inv = 1.0 / 1.5;
// double carry = 0.0;
// for (int i = 0; i < m_bars; ++i) {
// carry = std::max(m_out[i], carry * inv);
// values[i] = carry;
// }
//
// // Right to left pass and combine
// carry = 0.0;
// for (int i = m_bars - 1; i >= 0; --i) {
// carry = std::max(m_out[i], carry * inv);
// values[i] = std::max(values[i], carry);
// }
// Update values
if (values != m_values) {
m_values = std::move(values);
emit valuesChanged(m_values);
}
}
void CavaProcessor::setBars(int bars) {
if (bars < 0) {
qWarning() << "CavaProcessor::setBars: bars must be greater than 0. "
"Setting to 0.";
bars = 0;
}
if (m_bars != bars) {
m_bars = bars;
reload();
}
}
void CavaProcessor::reload() {
cleanup();
initCava();
}
void CavaProcessor::cleanup() {
if (m_plan) {
cava_destroy(m_plan);
m_plan = nullptr;
}
if (m_out) {
delete[] m_out;
m_out = nullptr;
}
}
void CavaProcessor::initCava() {
if (m_plan || m_bars == 0) {
return;
}
m_plan = cava_init(m_bars, ac::SAMPLE_RATE, 1, 1, 0.55, 50, 10000);
m_out = new double[static_cast<size_t>(m_bars)];
}
CavaProvider::CavaProvider(QObject* parent)
: AudioProvider(parent), m_bars(0), m_values(m_bars, 0.0) {
m_processor = new CavaProcessor();
init();
connect(
static_cast<CavaProcessor*>(m_processor),
&CavaProcessor::valuesChanged,
this,
&CavaProvider::updateValues);
}
int CavaProvider::bars() const {
return m_bars;
}
void CavaProvider::setBars(int bars) {
if (bars < 0) {
qWarning() << "CavaProvider::setBars: bars must be greater than 0. "
"Setting to 0.";
bars = 0;
}
if (m_bars == bars) {
return;
}
m_values.resize(bars, 0.0);
m_bars = bars;
emit barsChanged();
emit valuesChanged();
QMetaObject::invokeMethod(
static_cast<CavaProcessor*>(m_processor),
&CavaProcessor::setBars,
Qt::QueuedConnection,
bars);
}
QVector<double> CavaProvider::values() const {
return m_values;
}
void CavaProvider::updateValues(QVector<double> values) {
if (values != m_values) {
m_values = values;
emit valuesChanged();
}
}
} // namespace ZShell::services