spek

Acoustic spectrum analyser
git clone http://git.hanabi.in/repos/spek.git
Log | Files | Refs | README

commit f4a2e3ce93fb4ab1c868dde4a7ed7751ba56b258
parent f2e2c16c55d78d192e53dc92f1877e88fd2b9458
Author: Alexander Kojevnikov <alexander@kojevnikov.com>
Date:   Fri,  7 May 2010 18:44:08 +1000

Replace GtkImage/GdkPixbuf with GtkDrawingArea/CairoImageSurface

Diffstat:
Msrc/spek-spectrogram.vala | 49++++++++++++++++++++++++++++++++++---------------
Msrc/spek-window.vala | 2+-
2 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/src/spek-spectrogram.vala b/src/spek-spectrogram.vala @@ -1,47 +1,62 @@ +using Cairo; using Gdk; using Gtk; namespace Spek { - class Spectrogram : Gtk.Image { + class Spectrogram : DrawingArea { private Source source; private const int THRESHOLD = -92; - private struct Color { uchar r; uchar g; uchar b; } + + private ImageSurface image; public Spectrogram () { + show_all (); } - public void show_file (string file_name) { - pixbuf = new Pixbuf (Colorspace.RGB, false, 8, allocation.width, allocation.height); - pixbuf.fill (0); + public void open (string file_name) { + image = new ImageSurface (Format.RGB24, allocation.width, allocation.height); source = new Source ( file_name, allocation.height, allocation.width, THRESHOLD, source_callback); + queue_draw (); } private void source_callback (int sample, float[] values) { var x = sample; - var rowstride = pixbuf.rowstride; - unowned uchar[] pixels = pixbuf.get_pixels (); + var stride = image.get_stride (); + unowned uchar[] data = image.get_data (); 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 ( 1f, Math.log10f (1f - THRESHOLD + values[y]) / Math.log10f (-THRESHOLD)); - var color = get_color (level); + uint32 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; + uint32 *p = &data[i]; + *p = color; + } + 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); } - queue_draw_area (allocation.x + sample, allocation.y, 1, allocation.height); + 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: // http://www.physics.sfasu.edu/astro/color/spectra.html - private Color get_color (float level) { + private uint32 get_color (float level) { level *= 0.6625f; float r = 0.0f, g = 0.0f, b = 0.0f; if (level >= 0f && level < 0.15f) { @@ -73,7 +88,11 @@ namespace Spek { } 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; } } } \ No newline at end of file diff --git a/src/spek-window.vala b/src/spek-window.vala @@ -33,7 +33,7 @@ namespace Spek { STOCK_CANCEL, ResponseType.CANCEL, STOCK_OPEN, ResponseType.ACCEPT, null); if (chooser.run () == ResponseType.ACCEPT) { - spectrogram.show_file (chooser.get_filename ()); + spectrogram.open (chooser.get_filename ()); } chooser.destroy (); }