commit fe96c4d1e323ab8e93d6b0a6c8948626ab6a387c
parent 22c477b4a2423640c2ed1da6bc2cf9f2f6c1cc42
Author: Alexander Kojevnikov <alexander@kojevnikov.com>
Date: Thu, 6 May 2010 19:55:21 +1000
Use the visible spectrum
Diffstat:
1 file changed, 53 insertions(+), 4 deletions(-)
diff --git a/src/spek-spectrogram.vala b/src/spek-spectrogram.vala
@@ -6,6 +6,8 @@ namespace Spek {
private Source source;
+ private struct Color { uchar r; uchar g; uchar b; }
+
public Spectrogram () {
}
@@ -22,12 +24,59 @@ namespace Spek {
for (int y = 0; y < values.length; y++) {
var i = (values.length - y - 1) * rowstride + x * 3;
var level = float.min (1f, Math.log10f (101f + values[y]) / 2f);
- var value = (uchar) (level * 255f);
- pixels[i] = value;
- pixels[i + 1] = value;
- pixels[i + 2] = value;
+ var color = get_color (level);
+ if (sample < 20) {
+ // TODO: allocate additional space for this.
+ color = get_color (((float) y) / values.length);
+ }
+ pixels[i] = color.r;
+ pixels[i + 1] = color.g;
+ pixels[i + 2] = color.b;
}
queue_draw_area (allocation.x + sample, allocation.y, 1, allocation.height);
}
+
+ // Modified version of Dan Bruton's algorithm:
+ // http://www.physics.sfasu.edu/astro/color/spectra.html
+ private Color get_color (float level) {
+ float r = 0.0f, g = 0.0f, b = 0.0f;
+ if (level >= 0f && level < 0.15f) {
+ r = (0.15f - level) / (0.15f + 0.075f);
+ g = 0.0f;
+ b = 1.0f;
+ } else if (level >= 0.15f && level < 0.275f) {
+ r = 0.0f;
+ g = (level - 0.15f) / (0.275f - 0.15f);
+ b = 1.0f;
+ } else if (level >= 0.275f && level < 0.325f) {
+ r = 0.0f;
+ g = 1.0f;
+ b = (0.325f - level) / (0.325f - 0.275f);
+ } else if (level >= 0.325f && level < 0.5f) {
+ r = (level - 0.325f) / (0.5f - 0.325f);
+ g = 1.0f;
+ b = 0.0f;
+ } else if (level >= 0.5f && level < 0.6625f) {
+ r = 1.0f;
+ g = (0.6625f - level) / (0.6625f - 0.5f);
+ b = 0.0f;
+ } else if (level >= 0.6625 && level <= 1.0f) {
+ r = 1.0f;
+ g = 0.0f;
+ b = 0.0f;
+ }
+
+ // Intensity correction.
+ float cf = 0.0f;
+ if (level >= 0 && level < 0.1f) {
+ cf = 0.3f + 0.7f * (level + 0.075f) / (0.1f + 0.075f);
+ } else if (level >= 0.1f && level <= 0.8f) {
+ cf = 1.0f;
+ } else if (level > 0.8f && level <= 1.0f) {
+ cf = 0.3f + 0.7f * (1.0f - level) / (1.0f - 0.8f);
+ }
+ cf *= 255f;
+ return { (uchar) (r * cf + 0.5f), (uchar) (g * cf + 0.5f), (uchar) (b * cf + 0.5f) };
+ }
}
}
\ No newline at end of file