Analyzer code cleanup and try to fix crash on Fedora
This commit is contained in:
parent
3694765611
commit
6d888eb51a
@ -27,14 +27,13 @@
|
|||||||
|
|
||||||
#include "analyzerbase.h"
|
#include "analyzerbase.h"
|
||||||
|
|
||||||
|
#include "core/logging.h"
|
||||||
#include "engine/enginebase.h"
|
#include "engine/enginebase.h"
|
||||||
|
|
||||||
// INSTRUCTIONS Base2D
|
// INSTRUCTIONS Base2D
|
||||||
// 1. do anything that depends on height() in init(), Base2D will call it before
|
// 1. do anything that depends on height() in init(), Base2D will call it before you are shown
|
||||||
// you are shown
|
|
||||||
// 2. otherwise you can use the constructor to initialise things
|
// 2. otherwise you can use the constructor to initialise things
|
||||||
// 3. reimplement analyze(), and paint to canvas(), Base2D will update the
|
// 3. reimplement analyze(), and paint to canvas(), Base2D will update the widget when you return control to it
|
||||||
// widget when you return control to it
|
|
||||||
// 4. if you want to manipulate the scope, reimplement transform()
|
// 4. if you want to manipulate the scope, reimplement transform()
|
||||||
// 5. for convenience <vector> <qpixmap.h> <qwdiget.h> are pre-included
|
// 5. for convenience <vector> <qpixmap.h> <qwdiget.h> are pre-included
|
||||||
// TODO make an INSTRUCTIONS file
|
// TODO make an INSTRUCTIONS file
|
||||||
@ -50,37 +49,32 @@ template class Analyzer::Base<QWidget>;
|
|||||||
|
|
||||||
Analyzer::Base::Base(QWidget *parent, uint scopeSize)
|
Analyzer::Base::Base(QWidget *parent, uint scopeSize)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
m_timeout(40) // msec
|
timeout_(40),
|
||||||
,
|
fht_(new FHT(scopeSize)),
|
||||||
m_fht(new FHT(scopeSize)),
|
engine_(nullptr),
|
||||||
m_engine(nullptr),
|
lastscope_(512),
|
||||||
m_lastScope(512),
|
|
||||||
current_chunk_(0),
|
current_chunk_(0),
|
||||||
new_frame_(false),
|
new_frame_(false),
|
||||||
is_playing_(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
|
// This is a standard transformation that should give an FFT scope that has bands for pretty analyzers
|
||||||
// an FFT scope that has bands for pretty analyzers
|
|
||||||
|
|
||||||
// NOTE resizing here is redundant as FHT routines only calculate FHT::size()
|
// NOTE: Resizing here is redundant as FHT routines only calculate FHT::size() values scope.resize( fht_->size() );
|
||||||
// values
|
|
||||||
// scope.resize( m_fht->size() );
|
|
||||||
|
|
||||||
float *front = static_cast<float*>(&scope.front());
|
float *front = static_cast<float*>(&scope.front());
|
||||||
|
|
||||||
float *f = new float[m_fht->size()];
|
float *f = new float[fht_->size()];
|
||||||
m_fht->copy(&f[0], front);
|
fht_->copy(&f[0], front);
|
||||||
m_fht->logSpectrum(front, &f[0]);
|
fht_->logSpectrum(front, &f[0]);
|
||||||
m_fht->scale(front, 1.0 / 20);
|
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;
|
delete[] f;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -90,28 +84,28 @@ void Analyzer::Base::paintEvent(QPaintEvent *e) {
|
|||||||
QPainter p(this);
|
QPainter p(this);
|
||||||
p.fillRect(e->rect(), palette().color(QPalette::Window));
|
p.fillRect(e->rect(), palette().color(QPalette::Window));
|
||||||
|
|
||||||
switch (m_engine->state()) {
|
switch (engine_->state()) {
|
||||||
case Engine::Playing: {
|
case Engine::Playing: {
|
||||||
const Engine::Scope& thescope = m_engine->scope(m_timeout);
|
const Engine::Scope& thescope = engine_->scope(timeout_);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
// convert to mono here - our built in analyzers need mono, but the engines provide interleaved pcm
|
// 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) {
|
for (uint x = 0; (int)x < fht_->size(); ++x) {
|
||||||
m_lastScope[x] = double(thescope[i] + thescope[i + 1]) / (2 * (1 << 15));
|
lastscope_[x] = double(thescope[i] + thescope[i + 1]) / (2 * (1 << 15));
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
is_playing_ = true;
|
is_playing_ = true;
|
||||||
transform(m_lastScope);
|
transform(lastscope_);
|
||||||
analyze(p, m_lastScope, new_frame_);
|
analyze(p, lastscope_, new_frame_);
|
||||||
|
|
||||||
// scope.resize( m_fht->size() );
|
lastscope_.resize(fht_->size());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Engine::Paused:
|
case Engine::Paused:
|
||||||
is_playing_ = false;
|
is_playing_ = false;
|
||||||
analyze(p, m_lastScope, new_frame_);
|
analyze(p, lastscope_, new_frame_);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -124,16 +118,18 @@ void Analyzer::Base::paintEvent(QPaintEvent *e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Analyzer::Base::resizeExponent(int exp) {
|
int Analyzer::Base::resizeExponent(int exp) {
|
||||||
|
|
||||||
if (exp < 3)
|
if (exp < 3)
|
||||||
exp = 3;
|
exp = 3;
|
||||||
else if (exp > 9)
|
else if (exp > 9)
|
||||||
exp = 9;
|
exp = 9;
|
||||||
|
|
||||||
if (exp != m_fht->sizeExp()) {
|
if (exp != fht_->sizeExp()) {
|
||||||
delete m_fht;
|
delete fht_;
|
||||||
m_fht = new FHT(exp);
|
fht_ = new FHT(exp);
|
||||||
}
|
}
|
||||||
return exp;
|
return exp;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Analyzer::Base::resizeForBands(int bands) {
|
int Analyzer::Base::resizeForBands(int bands) {
|
||||||
@ -153,12 +149,11 @@ int Analyzer::Base::resizeForBands(int bands) {
|
|||||||
exp = 9;
|
exp = 9;
|
||||||
|
|
||||||
resizeExponent(exp);
|
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
|
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);
|
s[i] = dt * (sin(M_PI + (i * M_PI) / s.size()) + 1.0);
|
||||||
|
|
||||||
analyze(p, s, new_frame_);
|
analyze(p, s, new_frame_);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
analyze(p, Scope(32, 0), new_frame_);
|
analyze(p, Scope(32, 0), new_frame_);
|
||||||
|
|
||||||
++t;
|
++t;
|
||||||
@ -179,7 +175,7 @@ void Analyzer::Base::demo(QPainter& p) // virtual
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Analyzer::Base::polishEvent() {
|
void Analyzer::Base::polishEvent() {
|
||||||
init(); // virtual
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Analyzer::interpolate(const Scope& inVec, Scope& outVec) {
|
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) {
|
for (uint i = 0; i < outVec.size(); ++i, pos += step) {
|
||||||
const double error = pos - std::floor(pos);
|
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;
|
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;
|
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) {
|
void Analyzer::initSin(Scope& v, const uint size) {
|
||||||
|
|
||||||
double step = (M_PI * 2) / size;
|
double step = (M_PI * 2) / size;
|
||||||
double radian = 0;
|
double radian = 0;
|
||||||
|
|
||||||
@ -212,12 +209,15 @@ void Analyzer::initSin(Scope& v, const uint size) {
|
|||||||
v.push_back(sin(radian));
|
v.push_back(sin(radian));
|
||||||
radian += step;
|
radian += step;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Analyzer::Base::timerEvent(QTimerEvent *e) {
|
void Analyzer::Base::timerEvent(QTimerEvent *e) {
|
||||||
|
|
||||||
QWidget::timerEvent(e);
|
QWidget::timerEvent(e);
|
||||||
if (e->timerId() != m_timer.timerId()) return;
|
if (e->timerId() != timer_.timerId()) return;
|
||||||
|
|
||||||
new_frame_ = true;
|
new_frame_ = true;
|
||||||
update();
|
update();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,17 +37,17 @@ class Base : public QWidget {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~Base() { delete m_fht; }
|
~Base() { delete fht_; }
|
||||||
|
|
||||||
uint timeout() const { return m_timeout; }
|
uint timeout() const { return timeout_; }
|
||||||
|
|
||||||
void set_engine(EngineBase *engine) { m_engine = engine; }
|
void set_engine(EngineBase *engine) { engine_ = engine; }
|
||||||
|
|
||||||
void changeTimeout(uint newTimeout) {
|
void changeTimeout(uint newTimeout) {
|
||||||
m_timeout = newTimeout;
|
timeout_ = newTimeout;
|
||||||
if (m_timer.isActive()) {
|
if (timer_.isActive()) {
|
||||||
m_timer.stop();
|
timer_.stop();
|
||||||
m_timer.start(m_timeout, this);
|
timer_.start(timeout_, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,13 +71,12 @@ class Base : public QWidget {
|
|||||||
virtual void demo(QPainter& p);
|
virtual void demo(QPainter& p);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QBasicTimer m_timer;
|
QBasicTimer timer_;
|
||||||
uint m_timeout;
|
uint timeout_;
|
||||||
FHT* m_fht;
|
FHT *fht_;
|
||||||
EngineBase* m_engine;
|
EngineBase *engine_;
|
||||||
Scope m_lastScope;
|
Scope lastscope_;
|
||||||
int current_chunk_;
|
int current_chunk_;
|
||||||
|
|
||||||
bool new_frame_;
|
bool new_frame_;
|
||||||
bool is_playing_;
|
bool is_playing_;
|
||||||
};
|
};
|
||||||
|
@ -26,109 +26,105 @@ const uint BlockAnalyzer::MIN_COLUMNS = 32; // arbituary
|
|||||||
const uint BlockAnalyzer::MAX_COLUMNS = 256; // must be 2**n
|
const uint BlockAnalyzer::MAX_COLUMNS = 256; // must be 2**n
|
||||||
const uint BlockAnalyzer::FADE_SIZE = 90;
|
const uint BlockAnalyzer::FADE_SIZE = 90;
|
||||||
|
|
||||||
const char *BlockAnalyzer::kName =
|
const char *BlockAnalyzer::kName = QT_TRANSLATE_NOOP("AnalyzerContainer", "Block analyzer");
|
||||||
QT_TRANSLATE_NOOP("AnalyzerContainer", "Block analyzer");
|
|
||||||
|
|
||||||
BlockAnalyzer::BlockAnalyzer(QWidget *parent)
|
BlockAnalyzer::BlockAnalyzer(QWidget *parent)
|
||||||
: Analyzer::Base(parent, 9),
|
: Analyzer::Base(parent, 9),
|
||||||
m_columns(0) // uint
|
columns_(0),
|
||||||
,
|
rows_(0),
|
||||||
m_rows(0) // uint
|
y_(0),
|
||||||
,
|
barpixmap_(1, 1),
|
||||||
m_y(0) // uint
|
topbarpixmap_(WIDTH, HEIGHT),
|
||||||
,
|
scope_(MIN_COLUMNS),
|
||||||
m_barPixmap(1, 1) // null qpixmaps cause crashes
|
store_(1 << 8, 0),
|
||||||
,
|
fade_bars_(FADE_SIZE),
|
||||||
m_topBarPixmap(WIDTH, HEIGHT),
|
fade_pos_(1 << 8, 50),
|
||||||
m_scope(MIN_COLUMNS) // Scope
|
fade_intensity_(1 << 8, 32) {
|
||||||
,
|
|
||||||
m_store(1 << 8, 0) // vector<uint>
|
|
||||||
,
|
|
||||||
m_fade_bars(FADE_SIZE) // vector<QPixmap>
|
|
||||||
,
|
|
||||||
m_fade_pos(1 << 8, 50) // vector<uint>
|
|
||||||
,
|
|
||||||
m_fade_intensity(1 << 8, 32) // vector<uint>
|
|
||||||
{
|
|
||||||
setMinimumSize(MIN_COLUMNS * (WIDTH + 1) - 1, MIN_ROWS * (HEIGHT + 1) - 1); //-1 is padding, no drawing takes place there
|
setMinimumSize(MIN_COLUMNS * (WIDTH + 1) - 1, MIN_ROWS * (HEIGHT + 1) - 1); //-1 is padding, no drawing takes place there
|
||||||
setMaximumWidth(MAX_COLUMNS * (WIDTH + 1) - 1);
|
setMaximumWidth(MAX_COLUMNS * (WIDTH + 1) - 1);
|
||||||
|
|
||||||
// mxcl says null pixmaps cause crashes, so let's play it safe
|
// mxcl says null pixmaps cause crashes, so let's play it safe
|
||||||
for (uint i = 0; i < FADE_SIZE; ++i) m_fade_bars[i] = QPixmap(1, 1);
|
for (uint i = 0; i < FADE_SIZE; ++i) fade_bars_[i] = QPixmap(1, 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockAnalyzer::~BlockAnalyzer() {}
|
BlockAnalyzer::~BlockAnalyzer() {}
|
||||||
|
|
||||||
void BlockAnalyzer::resizeEvent(QResizeEvent *e) {
|
void BlockAnalyzer::resizeEvent(QResizeEvent *e) {
|
||||||
|
|
||||||
QWidget::resizeEvent(e);
|
QWidget::resizeEvent(e);
|
||||||
|
|
||||||
m_background = QPixmap(size());
|
background_ = QPixmap(size());
|
||||||
canvas_ = QPixmap(size());
|
canvas_ = QPixmap(size());
|
||||||
|
|
||||||
const uint oldRows = m_rows;
|
const uint oldRows = rows_;
|
||||||
|
|
||||||
// all is explained in analyze()..
|
// all is explained in analyze()..
|
||||||
//+1 to counter -1 in maxSizes, trust me we need this!
|
//+1 to counter -1 in maxSizes, trust me we need this!
|
||||||
m_columns = qMax(uint(double(width() + 1) / (WIDTH + 1)), MAX_COLUMNS);
|
columns_ = qMax(uint(double(width() + 1) / (WIDTH + 1)), MAX_COLUMNS);
|
||||||
m_rows = uint(double(height() + 1) / (HEIGHT + 1));
|
rows_ = uint(double(height() + 1) / (HEIGHT + 1));
|
||||||
|
|
||||||
// this is the y-offset for drawing from the top of the widget
|
// this is the y-offset for drawing from the top of the widget
|
||||||
m_y = (height() - (m_rows * (HEIGHT + 1)) + 2) / 2;
|
y_ = (height() - (rows_ * (HEIGHT + 1)) + 2) / 2;
|
||||||
|
|
||||||
m_scope.resize(m_columns);
|
scope_.resize(columns_);
|
||||||
|
|
||||||
if (m_rows != oldRows) {
|
if (rows_ != oldRows) {
|
||||||
m_barPixmap = QPixmap(WIDTH, m_rows * (HEIGHT + 1));
|
barpixmap_ = QPixmap(WIDTH, rows_ * (HEIGHT + 1));
|
||||||
|
|
||||||
for (uint i = 0; i < FADE_SIZE; ++i)
|
for (uint i = 0; i < FADE_SIZE; ++i)
|
||||||
m_fade_bars[i] = QPixmap(WIDTH, m_rows * (HEIGHT + 1));
|
fade_bars_[i] = QPixmap(WIDTH, rows_ * (HEIGHT + 1));
|
||||||
|
|
||||||
m_yscale.resize(m_rows + 1);
|
yscale_.resize(rows_ + 1);
|
||||||
|
|
||||||
const uint PRE = 1,
|
const uint PRE = 1, PRO = 1; // PRE and PRO allow us to restrict the range somewhat
|
||||||
PRO = 1; // PRE and PRO allow us to restrict the range somewhat
|
|
||||||
|
|
||||||
for (uint z = 0; z < m_rows; ++z)
|
for (uint z = 0; z < rows_; ++z)
|
||||||
m_yscale[z] = 1 - (log10(PRE + z) / log10(PRE + m_rows + PRO));
|
yscale_[z] = 1 - (log10(PRE + z) / log10(PRE + rows_ + PRO));
|
||||||
|
|
||||||
m_yscale[m_rows] = 0;
|
yscale_[rows_] = 0;
|
||||||
|
|
||||||
determineStep();
|
determineStep();
|
||||||
paletteChange(palette());
|
paletteChange(palette());
|
||||||
}
|
}
|
||||||
|
|
||||||
drawBackground();
|
drawBackground();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockAnalyzer::determineStep() {
|
void BlockAnalyzer::determineStep() {
|
||||||
|
|
||||||
// falltime is dependent on rowcount due to our digital resolution (ie we have boxes/blocks of pixels)
|
// falltime is dependent on rowcount due to our digital resolution (ie we have boxes/blocks of pixels)
|
||||||
// I calculated the value 30 based on some trial and error
|
// I calculated the value 30 based on some trial and error
|
||||||
|
|
||||||
// the fall time of 30 is too slow on framerates above 50fps
|
// the fall time of 30 is too slow on framerates above 50fps
|
||||||
const double fallTime = timeout() < 20 ? 20 * m_rows : 30 * m_rows;
|
const double fallTime = timeout() < 20 ? 20 * rows_ : 30 * rows_;
|
||||||
|
|
||||||
|
step_ = double(rows_ * timeout()) / fallTime;
|
||||||
|
|
||||||
m_step = double(m_rows * timeout()) / fallTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockAnalyzer::framerateChanged() { // virtual
|
void BlockAnalyzer::framerateChanged() {
|
||||||
determineStep();
|
determineStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockAnalyzer::transform(Analyzer::Scope& s) // pure virtual
|
void BlockAnalyzer::transform(Analyzer::Scope &s) {
|
||||||
{
|
|
||||||
for (uint x = 0; x < s.size(); ++x) s[x] *= 2;
|
for (uint x = 0; x < s.size(); ++x) s[x] *= 2;
|
||||||
|
|
||||||
float* front = static_cast<float*>(&s.front());
|
float* front = static_cast<float*>(&s.front());
|
||||||
|
|
||||||
m_fht->spectrum(front);
|
fht_->spectrum(front);
|
||||||
m_fht->scale(front, 1.0 / 20);
|
fht_->scale(front, 1.0 / 20);
|
||||||
|
|
||||||
|
// the second half is pretty dull, so only show it if the user has a large analyzer by setting to scope_.size() if large we prevent interpolation of large analyzers, this is good!
|
||||||
|
s.resize(scope_.size() <= MAX_COLUMNS / 2 ? MAX_COLUMNS / 2 : scope_.size());
|
||||||
|
|
||||||
// the second half is pretty dull, so only show it if the user has a large analyzer by setting to m_scope.size() if large we prevent interpolation of large analyzers, this is good!
|
|
||||||
s.resize(m_scope.size() <= MAX_COLUMNS / 2 ? MAX_COLUMNS / 2 : m_scope.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockAnalyzer::analyze(QPainter& p, const Analyzer::Scope& s,
|
void BlockAnalyzer::analyze(QPainter &p, const Analyzer::Scope &s, bool new_frame) {
|
||||||
bool new_frame) {
|
|
||||||
// y = 2 3 2 1 0 2
|
// y = 2 3 2 1 0 2
|
||||||
// . . . . # .
|
// . . . . # .
|
||||||
// . . . # # .
|
// . . . # # .
|
||||||
@ -139,7 +135,7 @@ void BlockAnalyzer::analyze(QPainter& p, const Analyzer::Scope& s,
|
|||||||
// y represents the number of blanks
|
// y represents the number of blanks
|
||||||
// y starts from the top and increases in units of blocks
|
// y starts from the top and increases in units of blocks
|
||||||
|
|
||||||
// m_yscale looks similar to: { 0.7, 0.5, 0.25, 0.15, 0.1, 0 }
|
// yscale_ looks similar to: { 0.7, 0.5, 0.25, 0.15, 0.1, 0 }
|
||||||
// if it contains 6 elements there are 5 rows in the analyzer
|
// if it contains 6 elements there are 5 rows in the analyzer
|
||||||
|
|
||||||
if (!new_frame) {
|
if (!new_frame) {
|
||||||
@ -149,50 +145,51 @@ void BlockAnalyzer::analyze(QPainter& p, const Analyzer::Scope& s,
|
|||||||
|
|
||||||
QPainter canvas_painter(&canvas_);
|
QPainter canvas_painter(&canvas_);
|
||||||
|
|
||||||
Analyzer::interpolate(s, m_scope);
|
Analyzer::interpolate(s, scope_);
|
||||||
|
|
||||||
// Paint the background
|
// Paint the background
|
||||||
canvas_painter.drawPixmap(0, 0, m_background);
|
canvas_painter.drawPixmap(0, 0, background_);
|
||||||
|
|
||||||
for (uint y, x = 0; x < m_scope.size(); ++x) {
|
for (uint y, x = 0; x < scope_.size(); ++x) {
|
||||||
// determine y
|
// determine y
|
||||||
for (y = 0; m_scope[x] < m_yscale[y]; ++y)
|
for (y = 0; scope_[x] < yscale_[y]; ++y) continue;
|
||||||
;
|
|
||||||
|
|
||||||
// this is opposite to what you'd think, higher than y means the bar is lower than y (physically)
|
// this is opposite to what you'd think, higher than y means the bar is lower than y (physically)
|
||||||
if ((float)y > m_store[x])
|
if ((float)y > store_[x])
|
||||||
y = int(m_store[x] += m_step);
|
y = int(store_[x] += step_);
|
||||||
else
|
else
|
||||||
m_store[x] = y;
|
store_[x] = y;
|
||||||
|
|
||||||
// if y is lower than m_fade_pos, then the bar has exceeded the height of the fadeout
|
// if y is lower than fade_pos_, then the bar has exceeded the height of the fadeout
|
||||||
// if the fadeout is quite faded now, then display the new one
|
// if the fadeout is quite faded now, then display the new one
|
||||||
if (y <= m_fade_pos[x] /*|| m_fade_intensity[x] < FADE_SIZE / 3*/) {
|
if (y <= fade_pos_[x] /*|| fade_intensity_[x] < FADE_SIZE / 3*/) {
|
||||||
m_fade_pos[x] = y;
|
fade_pos_[x] = y;
|
||||||
m_fade_intensity[x] = FADE_SIZE;
|
fade_intensity_[x] = FADE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_fade_intensity[x] > 0) {
|
if (fade_intensity_[x] > 0) {
|
||||||
const uint offset = --m_fade_intensity[x];
|
const uint offset = --fade_intensity_[x];
|
||||||
const uint y = m_y + (m_fade_pos[x] * (HEIGHT + 1));
|
const uint y = y_ + (fade_pos_[x] * (HEIGHT + 1));
|
||||||
canvas_painter.drawPixmap(x * (WIDTH + 1), y, m_fade_bars[offset], 0, 0, WIDTH, height() - y);
|
canvas_painter.drawPixmap(x * (WIDTH + 1), y, fade_bars_[offset], 0, 0, WIDTH, height() - y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_fade_intensity[x] == 0) m_fade_pos[x] = m_rows;
|
if (fade_intensity_[x] == 0) fade_pos_[x] = rows_;
|
||||||
|
|
||||||
// REMEMBER: y is a number from 0 to m_rows, 0 means all blocks are glowing, m_rows means none are
|
// REMEMBER: y is a number from 0 to rows_, 0 means all blocks are glowing, rows_ means none are
|
||||||
canvas_painter.drawPixmap(x * (WIDTH + 1), y * (HEIGHT + 1) + m_y, *bar(),
|
canvas_painter.drawPixmap(x * (WIDTH + 1), y * (HEIGHT + 1) + y_, *bar(),
|
||||||
0, y * (HEIGHT + 1), bar()->width(),
|
0, y * (HEIGHT + 1), bar()->width(),
|
||||||
bar()->height());
|
bar()->height());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint x = 0; x < m_store.size(); ++x)
|
for (uint x = 0; x < store_.size(); ++x)
|
||||||
canvas_painter.drawPixmap(x * (WIDTH + 1), int(m_store[x]) * (HEIGHT + 1) + m_y, m_topBarPixmap);
|
canvas_painter.drawPixmap(x * (WIDTH + 1), int(store_[x]) * (HEIGHT + 1) + y_, topbarpixmap_);
|
||||||
|
|
||||||
p.drawPixmap(0, 0, canvas_);
|
p.drawPixmap(0, 0, canvas_);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void adjustToLimits(int& b, int& f, uint& amount) {
|
static inline void adjustToLimits(int &b, int &f, uint &amount) {
|
||||||
|
|
||||||
// with a range of 0-255 and maximum adjustment of amount, maximise the difference between f and b
|
// with a range of 0-255 and maximum adjustment of amount, maximise the difference between f and b
|
||||||
|
|
||||||
if (b < f) {
|
if (b < f) {
|
||||||
@ -215,6 +212,7 @@ static inline void adjustToLimits(int& b, int& f, uint& amount) {
|
|||||||
f = 255;
|
f = 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -225,17 +223,18 @@ static inline void adjustToLimits(int& b, int& f, uint& amount) {
|
|||||||
* It won't modify the hue of fg unless absolutely necessary
|
* It won't modify the hue of fg unless absolutely necessary
|
||||||
* @return the adjusted form of fg
|
* @return the adjusted form of fg
|
||||||
*/
|
*/
|
||||||
QColor ensureContrast(const QColor& bg, const QColor& fg, uint _amount = 150) {
|
QColor ensureContrast(const QColor &bg, const QColor &fg, uint _amount = 150) {
|
||||||
|
|
||||||
class OutputOnExit {
|
class OutputOnExit {
|
||||||
public:
|
public:
|
||||||
OutputOnExit(const QColor& color) : c(color) {}
|
OutputOnExit(const QColor &color) : c(color) {}
|
||||||
~OutputOnExit() {
|
~OutputOnExit() {
|
||||||
int h, s, v;
|
int h, s, v;
|
||||||
c.getHsv(&h, &s, &v);
|
c.getHsv(&h, &s, &v);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QColor& c;
|
const QColor &c;
|
||||||
};
|
};
|
||||||
|
|
||||||
// hack so I don't have to cast everywhere
|
// hack so I don't have to cast everywhere
|
||||||
@ -352,24 +351,25 @@ QColor ensureContrast(const QColor& bg, const QColor& fg, uint _amount = 150) {
|
|||||||
|
|
||||||
#undef amount
|
#undef amount
|
||||||
// #undef STAMP
|
// #undef STAMP
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockAnalyzer::paletteChange(const QPalette&) // virtual
|
void BlockAnalyzer::paletteChange(const QPalette&) {
|
||||||
{
|
|
||||||
const QColor bg = palette().color(QPalette::Background);
|
const QColor bg = palette().color(QPalette::Background);
|
||||||
const QColor fg = ensureContrast(bg, palette().color(QPalette::Highlight));
|
const QColor fg = ensureContrast(bg, palette().color(QPalette::Highlight));
|
||||||
|
|
||||||
m_topBarPixmap.fill(fg);
|
topbarpixmap_.fill(fg);
|
||||||
|
|
||||||
const double dr = 15 * double(bg.red() - fg.red()) / (m_rows * 16);
|
const double dr = 15 * double(bg.red() - fg.red()) / (rows_ * 16);
|
||||||
const double dg = 15 * double(bg.green() - fg.green()) / (m_rows * 16);
|
const double dg = 15 * double(bg.green() - fg.green()) / (rows_ * 16);
|
||||||
const double db = 15 * double(bg.blue() - fg.blue()) / (m_rows * 16);
|
const double db = 15 * double(bg.blue() - fg.blue()) / (rows_ * 16);
|
||||||
const int r = fg.red(), g = fg.green(), b = fg.blue();
|
const int r = fg.red(), g = fg.green(), b = fg.blue();
|
||||||
|
|
||||||
bar()->fill(bg);
|
bar()->fill(bg);
|
||||||
|
|
||||||
QPainter p(bar());
|
QPainter p(bar());
|
||||||
for (int y = 0; (uint)y < m_rows; ++y)
|
for (int y = 0; (uint)y < rows_; ++y)
|
||||||
// graduate the fg color
|
// graduate the fg color
|
||||||
p.fillRect(0, y * (HEIGHT + 1), WIDTH, HEIGHT, QColor(r + int(dr * y), g + int(dg * y), b + int(db * y)));
|
p.fillRect(0, y * (HEIGHT + 1), WIDTH, HEIGHT, QColor(r + int(dr * y), g + int(dg * y), b + int(db * y)));
|
||||||
|
|
||||||
@ -389,9 +389,9 @@ void BlockAnalyzer::paletteChange(const QPalette&) // virtual
|
|||||||
|
|
||||||
// Precalculate all fade-bar pixmaps
|
// Precalculate all fade-bar pixmaps
|
||||||
for (uint y = 0; y < FADE_SIZE; ++y) {
|
for (uint y = 0; y < FADE_SIZE; ++y) {
|
||||||
m_fade_bars[y].fill(palette().color(QPalette::Background));
|
fade_bars_[y].fill(palette().color(QPalette::Background));
|
||||||
QPainter f(&m_fade_bars[y]);
|
QPainter f(&fade_bars_[y]);
|
||||||
for (int z = 0; (uint)z < m_rows; ++z) {
|
for (int z = 0; (uint)z < rows_; ++z) {
|
||||||
const double Y = 1.0 - (log10(FADE_SIZE - y) / log10(FADE_SIZE));
|
const double Y = 1.0 - (log10(FADE_SIZE - y) / log10(FADE_SIZE));
|
||||||
f.fillRect(0, z * (HEIGHT + 1), WIDTH, HEIGHT, QColor(r + int(dr * Y), g + int(dg * Y), b + int(db * Y)));
|
f.fillRect(0, z * (HEIGHT + 1), WIDTH, HEIGHT, QColor(r + int(dr * Y), g + int(dg * Y), b + int(db * Y)));
|
||||||
}
|
}
|
||||||
@ -399,16 +399,19 @@ void BlockAnalyzer::paletteChange(const QPalette&) // virtual
|
|||||||
}
|
}
|
||||||
|
|
||||||
drawBackground();
|
drawBackground();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockAnalyzer::drawBackground() {
|
void BlockAnalyzer::drawBackground() {
|
||||||
|
|
||||||
const QColor bg = palette().color(QPalette::Background);
|
const QColor bg = palette().color(QPalette::Background);
|
||||||
const QColor bgdark = bg.dark(112);
|
const QColor bgdark = bg.dark(112);
|
||||||
|
|
||||||
m_background.fill(bg);
|
background_.fill(bg);
|
||||||
|
|
||||||
|
QPainter p(&background_);
|
||||||
|
for (int x = 0; (uint)x < columns_; ++x)
|
||||||
|
for (int y = 0; (uint)y < rows_; ++y)
|
||||||
|
p.fillRect(x * (WIDTH + 1), y * (HEIGHT + 1) + y_, WIDTH, HEIGHT, bgdark);
|
||||||
|
|
||||||
QPainter p(&m_background);
|
|
||||||
for (int x = 0; (uint)x < m_columns; ++x)
|
|
||||||
for (int y = 0; (uint)y < m_rows; ++y)
|
|
||||||
p.fillRect(x * (WIDTH + 1), y * (HEIGHT + 1) + m_y, WIDTH, HEIGHT, bgdark);
|
|
||||||
}
|
}
|
||||||
|
@ -51,24 +51,24 @@ class BlockAnalyzer : public Analyzer::Base {
|
|||||||
void determineStep();
|
void determineStep();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPixmap* bar() { return &m_barPixmap; }
|
QPixmap *bar() { return &barpixmap_; }
|
||||||
|
|
||||||
uint m_columns, m_rows; // number of rows and columns of blocks
|
uint columns_, rows_; // number of rows and columns of blocks
|
||||||
uint m_y; // y-offset from top of widget
|
uint y_; // y-offset from top of widget
|
||||||
QPixmap m_barPixmap;
|
QPixmap barpixmap_;
|
||||||
QPixmap m_topBarPixmap;
|
QPixmap topbarpixmap_;
|
||||||
QPixmap m_background;
|
QPixmap background_;
|
||||||
QPixmap canvas_;
|
QPixmap canvas_;
|
||||||
Analyzer::Scope m_scope; // so we don't create a vector every frame
|
Analyzer::Scope scope_; // so we don't create a vector every frame
|
||||||
std::vector<float> m_store; // current bar heights
|
std::vector<float> store_; // current bar heights
|
||||||
std::vector<float> m_yscale;
|
std::vector<float> yscale_;
|
||||||
|
|
||||||
// FIXME why can't I namespace these? c++ issue?
|
// FIXME why can't I namespace these? c++ issue?
|
||||||
std::vector<QPixmap> m_fade_bars;
|
std::vector<QPixmap> fade_bars_;
|
||||||
std::vector<uint> m_fade_pos;
|
std::vector<uint> fade_pos_;
|
||||||
std::vector<int> m_fade_intensity;
|
std::vector<int> fade_intensity_;
|
||||||
|
|
||||||
float m_step; // rows to fall per frame
|
float step_; // rows to fall per frame
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user