Analyzer code cleanup and try to fix crash on Fedora

This commit is contained in:
Jonas Kvinge
2018-09-30 15:32:21 +02:00
parent 3694765611
commit 6d888eb51a
4 changed files with 160 additions and 158 deletions

View File

@@ -27,14 +27,13 @@
#include "analyzerbase.h"
#include "core/logging.h"
#include "engine/enginebase.h"
// INSTRUCTIONS Base2D
// 1. do anything that depends on height() in init(), Base2D will call it before
// you are shown
// 1. do anything that depends on height() in init(), Base2D will call it before you are shown
// 2. otherwise you can use the constructor to initialise things
// 3. reimplement analyze(), and paint to canvas(), Base2D will update the
// widget when you return control to it
// 3. reimplement analyze(), and paint to canvas(), Base2D will update the widget when you return control to it
// 4. if you want to manipulate the scope, reimplement transform()
// 5. for convenience <vector> <qpixmap.h> <qwdiget.h> are pre-included
// TODO make an INSTRUCTIONS file
@@ -50,37 +49,32 @@ template class Analyzer::Base<QWidget>;
Analyzer::Base::Base(QWidget *parent, uint scopeSize)
: QWidget(parent),
m_timeout(40) // msec
,
m_fht(new FHT(scopeSize)),
m_engine(nullptr),
m_lastScope(512),
timeout_(40),
fht_(new FHT(scopeSize)),
engine_(nullptr),
lastscope_(512),
current_chunk_(0),
new_frame_(false),
is_playing_(false) {}
void Analyzer::Base::hideEvent(QHideEvent*) { m_timer.stop(); }
void Analyzer::Base::hideEvent(QHideEvent*) { timer_.stop(); }
void Analyzer::Base::showEvent(QShowEvent*) { m_timer.start(timeout(), this); }
void Analyzer::Base::showEvent(QShowEvent*) { timer_.start(timeout(), this); }
void Analyzer::Base::transform(Scope& scope) // virtual
{
void Analyzer::Base::transform(Scope& scope) {
// this is a standard transformation that should give
// an FFT scope that has bands for pretty analyzers
// This is a standard transformation that should give an FFT scope that has bands for pretty analyzers
// NOTE resizing here is redundant as FHT routines only calculate FHT::size()
// values
// scope.resize( m_fht->size() );
// NOTE: Resizing here is redundant as FHT routines only calculate FHT::size() values scope.resize( fht_->size() );
float *front = static_cast<float*>(&scope.front());
float *f = new float[m_fht->size()];
m_fht->copy(&f[0], front);
m_fht->logSpectrum(front, &f[0]);
m_fht->scale(front, 1.0 / 20);
float *f = new float[fht_->size()];
fht_->copy(&f[0], front);
fht_->logSpectrum(front, &f[0]);
fht_->scale(front, 1.0 / 20);
scope.resize(m_fht->size() / 2); // second half of values are rubbish
scope.resize(fht_->size() / 2); // second half of values are rubbish
delete[] f;
}
@@ -90,28 +84,28 @@ void Analyzer::Base::paintEvent(QPaintEvent *e) {
QPainter p(this);
p.fillRect(e->rect(), palette().color(QPalette::Window));
switch (m_engine->state()) {
switch (engine_->state()) {
case Engine::Playing: {
const Engine::Scope& thescope = m_engine->scope(m_timeout);
const Engine::Scope& thescope = engine_->scope(timeout_);
int i = 0;
// convert to mono here - our built in analyzers need mono, but the engines provide interleaved pcm
for (uint x = 0; (int)x < m_fht->size(); ++x) {
m_lastScope[x] = double(thescope[i] + thescope[i + 1]) / (2 * (1 << 15));
for (uint x = 0; (int)x < fht_->size(); ++x) {
lastscope_[x] = double(thescope[i] + thescope[i + 1]) / (2 * (1 << 15));
i += 2;
}
is_playing_ = true;
transform(m_lastScope);
analyze(p, m_lastScope, new_frame_);
transform(lastscope_);
analyze(p, lastscope_, new_frame_);
// scope.resize( m_fht->size() );
lastscope_.resize(fht_->size());
break;
}
case Engine::Paused:
is_playing_ = false;
analyze(p, m_lastScope, new_frame_);
analyze(p, lastscope_, new_frame_);
break;
default:
@@ -124,16 +118,18 @@ void Analyzer::Base::paintEvent(QPaintEvent *e) {
}
int Analyzer::Base::resizeExponent(int exp) {
if (exp < 3)
exp = 3;
else if (exp > 9)
exp = 9;
if (exp != m_fht->sizeExp()) {
delete m_fht;
m_fht = new FHT(exp);
if (exp != fht_->sizeExp()) {
delete fht_;
fht_ = new FHT(exp);
}
return exp;
}
int Analyzer::Base::resizeForBands(int bands) {
@@ -153,12 +149,11 @@ int Analyzer::Base::resizeForBands(int bands) {
exp = 9;
resizeExponent(exp);
return m_fht->size() / 2;
return fht_->size() / 2;
}
void Analyzer::Base::demo(QPainter& p) // virtual
{
void Analyzer::Base::demo(QPainter& p) {
static int t = 201; // FIXME make static to namespace perhaps
@@ -171,7 +166,8 @@ void Analyzer::Base::demo(QPainter& p) // virtual
s[i] = dt * (sin(M_PI + (i * M_PI) / s.size()) + 1.0);
analyze(p, s, new_frame_);
} else
}
else
analyze(p, Scope(32, 0), new_frame_);
++t;
@@ -179,7 +175,7 @@ void Analyzer::Base::demo(QPainter& p) // virtual
}
void Analyzer::Base::polishEvent() {
init(); // virtual
init();
}
void Analyzer::interpolate(const Scope& inVec, Scope& outVec) {
@@ -189,13 +185,13 @@ void Analyzer::interpolate(const Scope& inVec, Scope& outVec) {
for (uint i = 0; i < outVec.size(); ++i, pos += step) {
const double error = pos - std::floor(pos);
const unsigned long offset = (unsigned long)pos;
const uint64_t offset = (uint64_t)pos;
unsigned long indexLeft = offset + 0;
uint64_t indexLeft = offset + 0;
if (indexLeft >= inVec.size()) indexLeft = inVec.size() - 1;
unsigned long indexRight = offset + 1;
uint64_t indexRight = offset + 1;
if (indexRight >= inVec.size()) indexRight = inVec.size() - 1;
@@ -205,6 +201,7 @@ void Analyzer::interpolate(const Scope& inVec, Scope& outVec) {
}
void Analyzer::initSin(Scope& v, const uint size) {
double step = (M_PI * 2) / size;
double radian = 0;
@@ -212,12 +209,15 @@ void Analyzer::initSin(Scope& v, const uint size) {
v.push_back(sin(radian));
radian += step;
}
}
void Analyzer::Base::timerEvent(QTimerEvent *e) {
QWidget::timerEvent(e);
if (e->timerId() != m_timer.timerId()) return;
if (e->timerId() != timer_.timerId()) return;
new_frame_ = true;
update();
}