|
From: Lasse Kärkkäi. <tr...@us...> - 2011-01-10 22:26:18
|
Module: editor
Branch: master
Commit: 516376705e3470ffc0c21f4a526588b925436f09
Author: Lasse Karkkainen <tro...@tr...>
Date: Mon Jan 10 23:25:27 2011 +0100
Refined pitch rendering.
---
pitchvis.cc | 17 ++++++++++++-----
pitchvis.hh | 26 ++++++++++++++++++--------
2 files changed, 30 insertions(+), 13 deletions(-)
diff --git a/pitchvis.cc b/pitchvis.cc
index 77fe9c1..4d78d3e 100644
--- a/pitchvis.cc
+++ b/pitchvis.cc
@@ -26,7 +26,7 @@ PitchVis::PitchVis(std::string const& filename): height(512) {
try { readVec(filename, data); } catch(std::exception& e) { std::cerr << e.what() << std::endl; return; }
unsigned step = 1024;
unsigned width = data.size() / step;
- img.resize(width * height);
+ img.resize(width * height, Pixel(0.5f, 0.5f, 0.5f, 1.0f));
Analyzer analyzer(44100, "");
MusicalScale scale;
QProgressDialog progress(tr("Analyzing and rendering pitch data..."), tr("&Abort"), 0, width, this);
@@ -40,10 +40,17 @@ PitchVis::PitchVis(std::string const& filename): height(512) {
analyzer.process();
Analyzer::Peaks peaks = analyzer.getPeaks();
for (unsigned i = 0; i < peaks.size(); ++i) {
- unsigned y = static_cast<unsigned>(8.0 * (scale.getNote(peaks[i].freq)));
- if (y >= height) continue;
- float value = magn2dB(peaks[i].magnitude) + 80.0;
- if (value > 0.0) (*this)(x, y).r += 0.01 * value;
+ unsigned y = height - static_cast<unsigned>(8.0 * (scale.getNote(peaks[i].freq)));
+ if (y == 0 || y >= height - 1) continue;
+ float value = 0.003 * (magn2dB(peaks[i].magnitude) + 80.0);
+ if (value < 0.0) continue;
+ Pixel p(value, value, value);
+ (*this)(x, y) += p;
+ p.r *= 0.5;
+ p.g *= 0.5;
+ p.b *= 0.5;
+ (*this)(x, y + 1) += p;
+ (*this)(x, y - 1) += p;
}
}
progress.setValue(width);
diff --git a/pitchvis.hh b/pitchvis.hh
index 639deec..a85a2ff 100644
--- a/pitchvis.hh
+++ b/pitchvis.hh
@@ -1,6 +1,8 @@
#pragma once
+#include "util.hh"
#include <QWidget>
+#include <cmath>
#include <string>
#include <vector>
@@ -8,16 +10,24 @@ struct Pixel {
float r,g,b,a;
Pixel(float r, float g, float b, float a = 1.0f): r(r), g(g), b(b), a(a) {}
Pixel(): r(), g(), b(), a(1.0f) {}
- unsigned rgba() {
- unsigned ret = 0;
- for (unsigned i = 0; i < 4; ++i) {
- float c = (*this)[i];
- unsigned char byte = static_cast<unsigned char>(0.5 + 255.0 * c * c); // c² is gamma correction
- ret |= byte << (i * 8);
- }
- return ret;
+ static unsigned char conv(float c, float a) {
+ return static_cast<unsigned char>(255.0 * a * std::sqrt(c)); // sqrt(c) is gamma correction
+ }
+ unsigned rgba() const {
+ unsigned char red = conv(r, a);
+ unsigned char green = conv(g, a);
+ unsigned char blue = conv(b, a);
+ unsigned char alpha = conv(1.0f, a);
+ return alpha << 24 | red << 16 | green << 8 | blue;
}
float& operator[](unsigned idx) { return (&r)[idx]; }
+ Pixel& operator+=(Pixel const& pix) {
+ r = clamp(r + pix.r);
+ g = clamp(g + pix.g);
+ b = clamp(b + pix.b);
+ a = clamp(a + pix.a);
+ return *this;
+ }
};
class PitchVis: public QWidget {
|