Refactor analyzers for new FHT modifications. Use QVectors where possible. Make readability changes in the code.

This commit is contained in:
santigl 2017-03-11 14:14:11 -03:00 committed by John Maguire
parent 6a19afde15
commit 6c9bc43bbb
9 changed files with 61 additions and 75 deletions

View File

@ -62,14 +62,13 @@ static const int sBarkBandCount = arraysize(sBarkBands);
Analyzer::Base::Base(QWidget* parent, uint scopeSize)
: QWidget(parent),
timeout_(40) // msec
,
timeout_(40), // msec
fht_(new FHT(scopeSize)),
engine_(nullptr),
lastScope_(512),
new_frame_(false),
is_playing_(false),
barkband_table_(QList<uint>()),
barkband_table_(),
prev_color_index_(0),
bands_(0),
psychedelic_enabled_(false) {}
@ -86,15 +85,17 @@ void Analyzer::Base::transform(Scope& scope) {
// values
// scope.resize( fht_->size() );
float* front = static_cast<float*>(&scope.front());
QVector<float> aux(fht_->size());
if (aux.size() >= scope.size()) {
qCopy(scope.begin(), scope.end(), aux.begin());
} else {
qCopy(scope.begin(), scope.begin() + aux.size(), aux.begin());
}
float* f = new float[fht_->size()];
fht_->copy(&f[0], front);
fht_->logSpectrum(front, &f[0]);
fht_->scale(front, 1.0 / 20);
fht_->logSpectrum(scope.data(), aux.data());
fht_->scale(scope.data(), 1.0 / 20);
scope.resize(fht_->size() / 2); // second half of values are rubbish
delete[] f;
}
void Analyzer::Base::paintEvent(QPaintEvent* e) {
@ -202,7 +203,7 @@ void Analyzer::Base::updateBandSize(const int scopeSize) {
bands_ = scopeSize;
barkband_table_.clear();
barkband_table_.reserve(bands_ + 1);
barkband_table_.resize(bands_ + 1);
int barkband = 0;
for (int i = 0; i < bands_ + 1; ++i) {
@ -218,7 +219,7 @@ void Analyzer::Base::updateBandSize(const int scopeSize) {
QColor Analyzer::Base::getPsychedelicColor(const Scope& scope,
const int ampFactor,
const int bias) {
if (scope.size() > barkband_table_.length()) {
if (scope.size() > barkband_table_.size()) {
return palette().color(QPalette::Highlight);
}
@ -232,15 +233,12 @@ QColor Analyzer::Base::getPsychedelicColor(const Scope& scope,
// Now divide the bark bands into thirds and compute their total amplitudes.
double rgb[3]{};
for (int i = 0; i < sBarkBandCount - 1; ++i) {
rgb[(i * 3) / sBarkBandCount] += bands[i] * bands[i];
rgb[(i * 3) / sBarkBandCount] += pow(bands[i], 2);
}
for (int i = 0; i < 3; ++i) {
// bias colours for a threshold around normally amplified audio
rgb[i] = (int)((sqrt(rgb[i]) * ampFactor) + bias);
if (rgb[i] > 255) {
rgb[i] = 255;
}
rgb[i] = qMin(255, (int)((sqrt(rgb[i]) * ampFactor) + bias));
}
return QColor::fromRgb(rgb[0], rgb[1], rgb[2]);

View File

@ -109,7 +109,7 @@ class Base : public QWidget {
bool new_frame_;
bool is_playing_;
QList<uint> barkband_table_;
QVector<uint> barkband_table_;
double prev_colors_[10][3];
int prev_color_index_;
int bands_;

View File

@ -100,8 +100,11 @@ void BarAnalyzer::colorChanged() {
rgb = palette().color(QPalette::Highlight);
}
for (int x = 0, r = rgb.red(), g = rgb.green(), b = rgb.blue(), r2 = 255 - r;
x < height(); ++x) {
for (int x = 0; x < height(); ++x) {
int r = rgb.red();
int g = rgb.green();
int b = rgb.blue();
int r2 = 255 - r;
for (int y = x; y > 0; --y) {
const double fraction = static_cast<double>(y) / height();
@ -121,7 +124,7 @@ void BarAnalyzer::psychedelicModeChanged(bool enabled) {
}
void BarAnalyzer::analyze(QPainter& p, const Scope& s, bool new_frame) {
if (!new_frame || engine_->state() == Engine::Paused) {
if (!new_frame || engine_->state() == Engine::Paused) {
p.drawPixmap(0, 0, canvas_);
return;
}

View File

@ -127,10 +127,8 @@ void BlockAnalyzer::framerateChanged() { // virtual
void BlockAnalyzer::transform(Analyzer::Scope& s) {
for (uint x = 0; x < s.size(); ++x) s[x] *= 2;
float* front = static_cast<float*>(&s.front());
fht_->spectrum(front);
fht_->scale(front, 1.0 / 20);
fht_->spectrum(s.data());
fht_->scale(s.data(), 1.0 / 20);
// the second half is pretty dull, so only show it if the user has a large
// analyzer

View File

@ -68,14 +68,13 @@ class BlockAnalyzer : public Analyzer::Base {
QPixmap topBarPixmap_;
QPixmap background_;
QPixmap canvas_;
Analyzer::Scope scope_; // so we don't create a vector every frame
std::vector<float> store_; // current bar kHeights
std::vector<float> yscale_;
Analyzer::Scope scope_; // so we don't create a vector every frame
QVector<float> store_; // current bar kHeights
QVector<float> yscale_;
// FIXME why can't I namespace these? c++ issue?
std::vector<QPixmap> fade_bars_;
std::vector<uint> fade_pos_;
std::vector<int> fade_intensity_;
QVector<QPixmap> fade_bars_;
QVector<uint> fade_pos_;
QVector<int> fade_intensity_;
float step_; // rows to fall per frame
};

View File

@ -93,10 +93,8 @@ void BoomAnalyzer::resizeEvent(QResizeEvent* e) {
}
void BoomAnalyzer::transform(Scope& s) {
float* front = static_cast<float*>(&s.front());
fht_->spectrum(front);
fht_->scale(front, 1.0 / 50);
fht_->spectrum(s.data());
fht_->scale(s.data(), 1.0 / 50);
s.resize(scope_.size() <= kMaxBandCount / 2 ? kMaxBandCount / 2
: scope_.size());

View File

@ -6,7 +6,7 @@
Copyright 2014, Krzysztof Sobiecki <sobkas@gmail.com>
Copyright 2014-2015, Mark Furneaux <mark@furneaux.ca>
Copyright 2015, Arun Narayanankutty <n.arun.lifescience@gmail.com>
Clementine is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
@ -26,19 +26,19 @@
#include <cmath>
#include <QTimerEvent>
#include <QBrush>
#include <QBrush>
#include "core/arraysize.h"
#include "core/logging.h"
using Analyzer::Scope;
const int Rainbow::RainbowAnalyzer::kHeight[] = { 21, 33 };
const int Rainbow::RainbowAnalyzer::kWidth[] = { 34, 53 };
const int Rainbow::RainbowAnalyzer::kFrameCount[] = { 6, 16 };
const int Rainbow::RainbowAnalyzer::kRainbowHeight[] = { 21, 16 };
const int Rainbow::RainbowAnalyzer::kRainbowOverlap[] = { 13, 15 };
const int Rainbow::RainbowAnalyzer::kSleepingHeight[] = { 24, 33 };
const int Rainbow::RainbowAnalyzer::kHeight[] = {21, 33};
const int Rainbow::RainbowAnalyzer::kWidth[] = {34, 53};
const int Rainbow::RainbowAnalyzer::kFrameCount[] = {6, 16};
const int Rainbow::RainbowAnalyzer::kRainbowHeight[] = {21, 16};
const int Rainbow::RainbowAnalyzer::kRainbowOverlap[] = {13, 15};
const int Rainbow::RainbowAnalyzer::kSleepingHeight[] = {24, 33};
const char* Rainbow::NyanCatAnalyzer::kName = "Nyanalyzer Cat";
const char* Rainbow::RainbowDashAnalyzer::kName = "Rainbow Dash";
@ -46,7 +46,8 @@ const float Rainbow::RainbowAnalyzer::kPixelScale = 0.02f;
Rainbow::RainbowAnalyzer::RainbowType Rainbow::RainbowAnalyzer::rainbowtype;
Rainbow::RainbowAnalyzer::RainbowAnalyzer(const RainbowType& rbtype, QWidget* parent)
Rainbow::RainbowAnalyzer::RainbowAnalyzer(const RainbowType& rbtype,
QWidget* parent)
: Analyzer::Base(parent, 9),
timer_id_(startTimer(kFrameIntervalMs)),
frame_(0),
@ -62,7 +63,7 @@ Rainbow::RainbowAnalyzer::RainbowAnalyzer(const RainbowType& rbtype, QWidget* pa
for (int i = 0; i < kRainbowBands; ++i) {
colors_[i] = QPen(QColor::fromHsv(i * 255 / kRainbowBands, 255, 255),
kRainbowHeight[rainbowtype] / kRainbowBands,
kRainbowHeight[rainbowtype] / kRainbowBands,
Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin);
// pow constants computed so that
@ -72,7 +73,7 @@ Rainbow::RainbowAnalyzer::RainbowAnalyzer(const RainbowType& rbtype, QWidget* pa
}
}
void Rainbow::RainbowAnalyzer::transform(Scope& s) { fht_->spectrum(&s.front()); }
void Rainbow::RainbowAnalyzer::transform(Scope& s) { fht_->spectrum(s.data()); }
void Rainbow::RainbowAnalyzer::timerEvent(QTimerEvent* e) {
if (e->timerId() == timer_id_) {
@ -88,15 +89,15 @@ void Rainbow::RainbowAnalyzer::resizeEvent(QResizeEvent* e) {
buffer_[0] = QPixmap();
buffer_[1] = QPixmap();
available_rainbow_width_ = width() - kWidth[rainbowtype]
+ kRainbowOverlap[rainbowtype];
available_rainbow_width_ =
width() - kWidth[rainbowtype] + kRainbowOverlap[rainbowtype];
px_per_frame_ =
static_cast<float>(available_rainbow_width_) / (kHistorySize - 1) + 1;
x_offset_ = px_per_frame_ * (kHistorySize - 1) - available_rainbow_width_;
}
void Rainbow::RainbowAnalyzer::analyze(QPainter& p, const Analyzer::Scope& s,
bool new_frame) {
bool new_frame) {
// Discard the second half of the transform
const int scope_size = s.size() / 2;
@ -129,15 +130,13 @@ void Rainbow::RainbowAnalyzer::analyze(QPainter& p, const Analyzer::Scope& s,
QPointF* dest = polyline;
float* source = history_;
const float top_of =
static_cast<float>(height()) / 2 - static_cast<float>(
kRainbowHeight[rainbowtype]) / 2;
const float top_of = static_cast<float>(height()) / 2 -
static_cast<float>(kRainbowHeight[rainbowtype]) / 2;
for (int band = 0; band < kRainbowBands; ++band) {
// Calculate the Y position of this band.
const float y =
static_cast<float>(kRainbowHeight[rainbowtype]) / (
kRainbowBands + 1) * (band + 0.5) +
top_of;
const float y = static_cast<float>(kRainbowHeight[rainbowtype]) /
(kRainbowBands + 1) * (band + 0.5) +
top_of;
// Add each point in the line.
for (int x = 0; x < kHistorySize; ++x) {
@ -178,7 +177,7 @@ void Rainbow::RainbowAnalyzer::analyze(QPainter& p, const Analyzer::Scope& s,
x_offset_ + available_rainbow_width_ - px_per_frame_, 0);
buffer_painter.fillRect(
x_offset_ + available_rainbow_width_ - px_per_frame_, 0,
kWidth[rainbowtype] - kRainbowOverlap[rainbowtype] + px_per_frame_,
kWidth[rainbowtype] - kRainbowOverlap[rainbowtype] + px_per_frame_,
height(), background_brush_);
for (int band = kRainbowBands - 1; band >= 0; --band) {
@ -196,18 +195,16 @@ void Rainbow::RainbowAnalyzer::analyze(QPainter& p, const Analyzer::Scope& s,
// Nyan nyan nyan nyan dash dash dash dash.
if (!is_playing_) {
// Ssshhh!
p.drawPixmap(SleepingDestRect(rainbowtype), cat_dash_[rainbowtype],
p.drawPixmap(SleepingDestRect(rainbowtype), cat_dash_[rainbowtype],
SleepingSourceRect(rainbowtype));
} else {
p.drawPixmap(DestRect(rainbowtype), cat_dash_[rainbowtype],
p.drawPixmap(DestRect(rainbowtype), cat_dash_[rainbowtype],
SourceRect(rainbowtype));
}
}
Rainbow::NyanCatAnalyzer::NyanCatAnalyzer(QWidget* parent)
:RainbowAnalyzer(Rainbow::RainbowAnalyzer::Nyancat, parent) {
}
: RainbowAnalyzer(Rainbow::RainbowAnalyzer::Nyancat, parent) {}
Rainbow::RainbowDashAnalyzer::RainbowDashAnalyzer(QWidget* parent)
:RainbowAnalyzer(Rainbow::RainbowAnalyzer::Dash, parent) {
}
: RainbowAnalyzer(Rainbow::RainbowAnalyzer::Dash, parent) {}

View File

@ -114,9 +114,8 @@ void Sonogram::analyze(QPainter& p, const Scope& s, bool new_frame) {
}
void Sonogram::transform(Scope& scope) {
float* front = static_cast<float*>(&scope.front());
fht_->power2(front);
fht_->scale(front, 1.0 / 256);
fht_->power2(scope.data());
fht_->scale(scope.data(), 1.0 / 256);
scope.resize(fht_->size() / 2);
}

View File

@ -40,7 +40,6 @@ void TurbineAnalyzer::analyze(QPainter& p, const Scope& scope, bool new_frame) {
return;
}
float h;
const uint hd2 = height() / 2;
const uint kMaxHeight = hd2 - 1;
@ -55,13 +54,10 @@ void TurbineAnalyzer::analyze(QPainter& p, const Scope& scope, bool new_frame) {
}
for (uint i = 0, x = 0, y; i < bands_; ++i, x += kColumnWidth + 1) {
h = log10(scope_[i] * 256.0) * F_ * 0.5;
if (h > kMaxHeight) h = kMaxHeight;
float h = std::min(log10(scope_[i] * 256.0) * F_ * 0.5, kMaxHeight * 1.0);
if (h > bar_height_[i]) {
bar_height_[i] = h;
if (h > peak_height_[i]) {
peak_height_[i] = h;
peak_speed_[i] = 0.01;
@ -75,13 +71,11 @@ void TurbineAnalyzer::analyze(QPainter& p, const Scope& scope, bool new_frame) {
}
peak_handling:
if (peak_height_[i] > 0.0) {
peak_height_[i] -= peak_speed_[i];
peak_speed_[i] *= F_peakSpeed_; // 1.12
if (peak_height_[i] < bar_height_[i]) peak_height_[i] = bar_height_[i];
if (peak_height_[i] < 0.0) peak_height_[i] = 0.0;
peak_height_[i] =
std::max(0.0f, std::max(bar_height_[i], peak_height_[i]));
}
}