Draw the spectrogram

This commit is contained in:
Alexander Kojevnikov 2012-08-15 09:46:50 -07:00
parent f81ce84826
commit 98b2cb0ab8
4 changed files with 29 additions and 25 deletions

View File

@ -115,6 +115,8 @@ struct spek_pipeline * spek_pipeline_open(
p->output = malloc(bands * sizeof(float));
spek_audio_start(p->cx, samples);
}
return p;
}
const struct spek_audio_properties * spek_pipeline_properties(struct spek_pipeline *pipeline)
@ -124,7 +126,7 @@ const struct spek_audio_properties * spek_pipeline_properties(struct spek_pipeli
void spek_pipeline_start(struct spek_pipeline *p)
{
if (!p->properties->error) return;
if (p->properties->error) return;
p->input_pos = 0;
p->worker_done = false;

View File

@ -26,6 +26,7 @@
BEGIN_EVENT_TABLE(SpekSpectrogram, wxPanel)
EVT_PAINT(SpekSpectrogram::on_paint)
EVT_SIZE(SpekSpectrogram::on_size)
END_EVENT_TABLE()
enum
@ -45,7 +46,8 @@ SpekSpectrogram::SpekSpectrogram(wxFrame *parent) :
wxPanel(parent, -1, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE),
pipeline(NULL),
palette(RULER, BANDS),
image()
image(1, 1),
prev_width(-1)
{
SetBackgroundStyle(wxBG_STYLE_CUSTOM);
@ -77,6 +79,17 @@ void SpekSpectrogram::on_paint(wxPaintEvent& evt)
render(dc);
}
void SpekSpectrogram::on_size(wxSizeEvent& evt)
{
wxSize size = GetClientSize();
bool width_changed = this->prev_width != size.GetWidth();
this->prev_width = size.GetWidth();
if (!this->path.IsEmpty() && width_changed) {
start();
}
}
void SpekSpectrogram::render(wxDC& dc)
{
wxSize size = GetClientSize();
@ -119,6 +132,12 @@ void SpekSpectrogram::render(wxDC& dc)
TPAD - 2 * GAP - 2 * normal_height
);
if (this->image.GetHeight() > 1) {
// Draw the spectrogram.
wxBitmap bmp(this->image.Scale(w - LPAD - RPAD, h - TPAD - BPAD /*TODO:, wxIMAGE_QUALITY_HIGH*/));
dc.DrawBitmap(bmp, LPAD, TPAD);
}
// Border around the spectrogram.
// TODO: check if this uses antialiasing
dc.DrawRectangle(LPAD, TPAD, w - LPAD - RPAD, h - TPAD - BPAD);
@ -139,20 +158,20 @@ void SpekSpectrogram::pipeline_cb(int sample, float *values, void *cb_data)
uint32_t color = get_color(level);
s->image.SetRGB(
sample,
y,
BANDS - y - 1,
color >> 16,
(color >> 8) & 0xFF,
color & 0xFF
);
}
s->Refresh(false); // TODO: refresh only one pixel column
s->Refresh(); // TODO: refresh only one pixel column
}
void SpekSpectrogram::start()
{
if(this->pipeline) {
if (this->pipeline) {
spek_pipeline_close(this->pipeline);
this->pipeline = NULL;
}
@ -178,7 +197,7 @@ void SpekSpectrogram::start()
this->image.Create(1, 1);
}
Refresh(false);
Refresh();
}
// Modified version of Dan Bruton's algorithm:

View File

@ -32,6 +32,7 @@ public:
private:
void on_paint(wxPaintEvent& evt);
void on_size(wxSizeEvent& evt);
void render(wxDC& dc);
void start();
@ -43,6 +44,7 @@ private:
wxString desc;
wxImage palette;
wxImage image;
int prev_width;
DECLARE_EVENT_TABLE()
};

View File

@ -36,18 +36,6 @@ namespace Spek {
surface.write_to_png (file_name);
}
private int prev_width = -1;
protected override void size_allocate (Gdk.Rectangle allocation) {
base.size_allocate (allocation);
bool width_changed = prev_width != allocation.width;
prev_width = allocation.width;
if (file_name != null && width_changed) {
start ();
}
}
protected override bool expose_event (EventExpose event) {
var window = get_window ();
var cr = cairo_create (window);
@ -64,13 +52,6 @@ namespace Spek {
int text_width, text_height;
if (image != null) {
// Draw the spectrogram.
cr.translate (LPAD, h - BPAD);
cr.scale (1, -(h - TPAD - BPAD) / image.get_height ());
cr.set_source_surface (image, 0, 0);
cr.paint ();
cr.identity_matrix ();
// Prepare to draw the rulers.
cr.set_source_rgb (1, 1, 1);
cr.set_line_width (1);