mirror of
https://github.com/alexkay/spek.git
synced 2025-06-10 04:12:20 +03:00
Replace GtkImage/GdkPixbuf with GtkDrawingArea/CairoImageSurface
This commit is contained in:
parent
f2e2c16c55
commit
f4a2e3ce93
@ -1,47 +1,62 @@
|
|||||||
|
using Cairo;
|
||||||
using Gdk;
|
using Gdk;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
|
|
||||||
namespace Spek {
|
namespace Spek {
|
||||||
class Spectrogram : Gtk.Image {
|
class Spectrogram : DrawingArea {
|
||||||
|
|
||||||
private Source source;
|
private Source source;
|
||||||
private const int THRESHOLD = -92;
|
private const int THRESHOLD = -92;
|
||||||
private struct Color { uchar r; uchar g; uchar b; }
|
|
||||||
|
private ImageSurface image;
|
||||||
|
|
||||||
public Spectrogram () {
|
public Spectrogram () {
|
||||||
|
show_all ();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void show_file (string file_name) {
|
public void open (string file_name) {
|
||||||
pixbuf = new Pixbuf (Colorspace.RGB, false, 8, allocation.width, allocation.height);
|
image = new ImageSurface (Format.RGB24, allocation.width, allocation.height);
|
||||||
pixbuf.fill (0);
|
|
||||||
source = new Source (
|
source = new Source (
|
||||||
file_name, allocation.height, allocation.width,
|
file_name, allocation.height, allocation.width,
|
||||||
THRESHOLD, source_callback);
|
THRESHOLD, source_callback);
|
||||||
|
queue_draw ();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void source_callback (int sample, float[] values) {
|
private void source_callback (int sample, float[] values) {
|
||||||
var x = sample;
|
var x = sample;
|
||||||
var rowstride = pixbuf.rowstride;
|
var stride = image.get_stride ();
|
||||||
unowned uchar[] pixels = pixbuf.get_pixels ();
|
unowned uchar[] data = image.get_data ();
|
||||||
for (int y = 0; y < values.length; y++) {
|
for (int y = 0; y < values.length; y++) {
|
||||||
var i = (values.length - y - 1) * rowstride + x * 3;
|
var i = (values.length - y - 1) * stride + x * 4;
|
||||||
var level = float.min (
|
var level = float.min (
|
||||||
1f, Math.log10f (1f - THRESHOLD + values[y]) / Math.log10f (-THRESHOLD));
|
1f, Math.log10f (1f - THRESHOLD + values[y]) / Math.log10f (-THRESHOLD));
|
||||||
var color = get_color (level);
|
uint32 color = get_color (level);
|
||||||
if (sample < 20) {
|
if (sample < 20) {
|
||||||
// TODO: allocate additional space for this.
|
// TODO: allocate additional space for this.
|
||||||
color = get_color (((float) y) / values.length);
|
color = get_color (((float) y) / values.length);
|
||||||
}
|
}
|
||||||
pixels[i] = color.r;
|
uint32 *p = &data[i];
|
||||||
pixels[i + 1] = color.g;
|
*p = color;
|
||||||
pixels[i + 2] = color.b;
|
|
||||||
}
|
}
|
||||||
queue_draw_area (allocation.x + sample, allocation.y, 1, allocation.height);
|
queue_draw_area (sample, 0, 1, allocation.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
private override bool expose_event (EventExpose event) {
|
||||||
|
var cr = cairo_create (this.window);
|
||||||
|
|
||||||
|
if (image == null) {
|
||||||
|
cr.set_source_rgb (0, 0, 0);
|
||||||
|
} else {
|
||||||
|
cr.set_source_surface (image, 0, 0);
|
||||||
|
}
|
||||||
|
cr.rectangle (event.area.x, event.area.y, event.area.width, event.area.height);
|
||||||
|
cr.fill ();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modified version of Dan Bruton's algorithm:
|
// Modified version of Dan Bruton's algorithm:
|
||||||
// http://www.physics.sfasu.edu/astro/color/spectra.html
|
// http://www.physics.sfasu.edu/astro/color/spectra.html
|
||||||
private Color get_color (float level) {
|
private uint32 get_color (float level) {
|
||||||
level *= 0.6625f;
|
level *= 0.6625f;
|
||||||
float r = 0.0f, g = 0.0f, b = 0.0f;
|
float r = 0.0f, g = 0.0f, b = 0.0f;
|
||||||
if (level >= 0f && level < 0.15f) {
|
if (level >= 0f && level < 0.15f) {
|
||||||
@ -73,7 +88,11 @@ namespace Spek {
|
|||||||
}
|
}
|
||||||
cf *= 255f;
|
cf *= 255f;
|
||||||
|
|
||||||
return { (uchar) (r * cf + 0.5f), (uchar) (g * cf + 0.5f), (uchar) (b * cf + 0.5f) };
|
// Pack RGB values into Cairo-happy format.
|
||||||
|
uint32 rr = (uint32) (r * cf + 0.5f);
|
||||||
|
uint32 gg = (uint32) (g * cf + 0.5f);
|
||||||
|
uint32 bb = (uint32) (b * cf + 0.5f);
|
||||||
|
return (rr << 16) + (gg << 8) + bb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -33,7 +33,7 @@ namespace Spek {
|
|||||||
STOCK_CANCEL, ResponseType.CANCEL,
|
STOCK_CANCEL, ResponseType.CANCEL,
|
||||||
STOCK_OPEN, ResponseType.ACCEPT, null);
|
STOCK_OPEN, ResponseType.ACCEPT, null);
|
||||||
if (chooser.run () == ResponseType.ACCEPT) {
|
if (chooser.run () == ResponseType.ACCEPT) {
|
||||||
spectrogram.show_file (chooser.get_filename ());
|
spectrogram.open (chooser.get_filename ());
|
||||||
}
|
}
|
||||||
chooser.destroy ();
|
chooser.destroy ();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user