mirror of
https://github.com/alexkay/spek.git
synced 2025-04-17 00:52:20 +03:00
Proper notification using custom events
This commit is contained in:
parent
4e71509218
commit
0b121ec1c5
@ -5,6 +5,8 @@ spek_SOURCES = \
|
||||
spek-audio-desc.hh \
|
||||
spek-audio.c \
|
||||
spek-audio.h \
|
||||
spek-events.cc \
|
||||
spek-events.hh \
|
||||
spek-fft.c \
|
||||
spek-fft.h \
|
||||
spek-palette.c \
|
||||
|
45
src/spek-events.cc
Normal file
45
src/spek-events.cc
Normal file
@ -0,0 +1,45 @@
|
||||
/* spek-events.cc
|
||||
*
|
||||
* Copyright (C) 2012 Alexander Kojevnikov <alexander@kojevnikov.com>
|
||||
*
|
||||
* Spek is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Spek is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Spek. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "spek-events.hh"
|
||||
|
||||
//IMPLEMENT_DYNAMIC_CLASS(SpekHaveSampleEvent, wxEvent)
|
||||
DEFINE_EVENT_TYPE(SPEK_HAVE_SAMPLE)
|
||||
|
||||
SpekHaveSampleEvent::SpekHaveSampleEvent(int bands, int sample, float *values, bool free_values)
|
||||
: wxEvent(), bands(bands), sample(sample), values(values), free_values(free_values)
|
||||
{
|
||||
SetEventType(SPEK_HAVE_SAMPLE);
|
||||
}
|
||||
|
||||
SpekHaveSampleEvent::SpekHaveSampleEvent(const SpekHaveSampleEvent& other)
|
||||
{
|
||||
SetEventType(SPEK_HAVE_SAMPLE);
|
||||
this->bands = other.bands;
|
||||
this->sample = other.sample;
|
||||
this->values = (float *)malloc(this->bands * sizeof(float));
|
||||
memcpy(this->values, other.values, this->bands * sizeof(float));
|
||||
this->free_values = true;
|
||||
}
|
||||
|
||||
SpekHaveSampleEvent::~SpekHaveSampleEvent()
|
||||
{
|
||||
if (this->free_values) {
|
||||
free(this->values);
|
||||
}
|
||||
}
|
53
src/spek-events.hh
Normal file
53
src/spek-events.hh
Normal file
@ -0,0 +1,53 @@
|
||||
/* spek-events.hh
|
||||
*
|
||||
* Copyright (C) 2012 Alexander Kojevnikov <alexander@kojevnikov.com>
|
||||
*
|
||||
* Spek is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Spek is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Spek. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SPEK_EVENTS_HH_
|
||||
#define SPEK_EVENTS_HH_
|
||||
|
||||
#include <wx/wx.h>
|
||||
|
||||
class SpekHaveSampleEvent: public wxEvent
|
||||
{
|
||||
public:
|
||||
SpekHaveSampleEvent(int bands, int sample, float *values, bool free_values);
|
||||
SpekHaveSampleEvent(const SpekHaveSampleEvent& other);
|
||||
~SpekHaveSampleEvent();
|
||||
|
||||
int get_bands() const { return this->bands; }
|
||||
int get_sample() const { return this->sample; }
|
||||
const float *get_values() const { return this->values; }
|
||||
|
||||
wxEvent *Clone() const { return new SpekHaveSampleEvent(*this); }
|
||||
// DECLARE_DYNAMIC_CLASS(SpekHaveSampleEvent);
|
||||
|
||||
private:
|
||||
int bands;
|
||||
int sample;
|
||||
float *values;
|
||||
bool free_values;
|
||||
};
|
||||
|
||||
typedef void (wxEvtHandler::*SpekHaveSampleEventFunction)(SpekHaveSampleEvent&);
|
||||
|
||||
DECLARE_EVENT_TYPE(SPEK_HAVE_SAMPLE, wxID_ANY)
|
||||
|
||||
#define SPEK_EVT_HAVE_SAMPLE(fn) \
|
||||
DECLARE_EVENT_TABLE_ENTRY(SPEK_HAVE_SAMPLE, -1, -1, \
|
||||
(wxObjectEventFunction) (SpekHaveSampleEventFunction) &fn, (wxObject *) NULL ),
|
||||
|
||||
#endif
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "spek-audio.h"
|
||||
#include "spek-audio-desc.hh"
|
||||
#include "spek-events.hh"
|
||||
#include "spek-palette.h"
|
||||
#include "spek-pipeline.h"
|
||||
#include "spek-platform.hh"
|
||||
@ -32,6 +33,7 @@ BEGIN_EVENT_TABLE(SpekSpectrogram, wxPanel)
|
||||
EVT_IDLE(SpekSpectrogram::on_idle)
|
||||
EVT_PAINT(SpekSpectrogram::on_paint)
|
||||
EVT_SIZE(SpekSpectrogram::on_size)
|
||||
SPEK_EVT_HAVE_SAMPLE(SpekSpectrogram::on_have_sample)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
enum
|
||||
@ -72,6 +74,11 @@ SpekSpectrogram::SpekSpectrogram(wxFrame *parent) :
|
||||
}
|
||||
}
|
||||
|
||||
SpekSpectrogram::~SpekSpectrogram()
|
||||
{
|
||||
this->stop();
|
||||
}
|
||||
|
||||
void SpekSpectrogram::open(const wxString& path)
|
||||
{
|
||||
this->path = path;
|
||||
@ -109,6 +116,30 @@ void SpekSpectrogram::on_size(wxSizeEvent& evt)
|
||||
}
|
||||
}
|
||||
|
||||
void SpekSpectrogram::on_have_sample(SpekHaveSampleEvent& event)
|
||||
{
|
||||
static double log10_threshold = log10(-THRESHOLD);
|
||||
int bands = event.get_bands();
|
||||
int sample = event.get_sample();
|
||||
const float *values = event.get_values();
|
||||
|
||||
for (int y = 0; y < bands; y++) {
|
||||
double level = log10(1.0 - THRESHOLD + values[y]) / log10_threshold;
|
||||
if (level > 1.0) level = 1.0;
|
||||
uint32_t color = spek_palette_spectrum(level);
|
||||
this->image.SetRGB(
|
||||
sample,
|
||||
bands - y - 1,
|
||||
color >> 16,
|
||||
(color >> 8) & 0xFF,
|
||||
color & 0xFF
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: refresh only one pixel column
|
||||
this->Refresh();
|
||||
}
|
||||
|
||||
static wxString time_formatter(int unit)
|
||||
{
|
||||
// TODO: i18n
|
||||
@ -261,36 +292,16 @@ void SpekSpectrogram::render(wxDC& dc)
|
||||
density_ruler.draw(dc);
|
||||
}
|
||||
|
||||
void SpekSpectrogram::pipeline_cb(int sample, float *values, void *cb_data)
|
||||
static void pipeline_cb(int sample, float *values, void *cb_data)
|
||||
{
|
||||
static double log10_threshold = log10(-THRESHOLD);
|
||||
SpekHaveSampleEvent event(BANDS, sample, values, false);
|
||||
SpekSpectrogram *s = (SpekSpectrogram *)cb_data;
|
||||
|
||||
for (int y = 0; y < BANDS; y++) {
|
||||
double level = log10(1.0 - THRESHOLD + values[y]) / log10_threshold;
|
||||
if (level > 1.0) level = 1.0;
|
||||
uint32_t color = spek_palette_spectrum(level);
|
||||
s->image.SetRGB(
|
||||
sample,
|
||||
BANDS - y - 1,
|
||||
color >> 16,
|
||||
(color >> 8) & 0xFF,
|
||||
color & 0xFF
|
||||
);
|
||||
}
|
||||
|
||||
s->Refresh(); // TODO: refresh only one pixel column
|
||||
wxWakeUpIdle();
|
||||
wxPostEvent(s, event);
|
||||
}
|
||||
|
||||
|
||||
void SpekSpectrogram::start()
|
||||
{
|
||||
if (this->pipeline) {
|
||||
spek_pipeline_close(this->pipeline);
|
||||
this->pipeline = NULL;
|
||||
this->properties = NULL;
|
||||
}
|
||||
this->stop();
|
||||
|
||||
// The number of samples is the number of pixels available for the image.
|
||||
// The number of bands is fixed, FFT results are very different for
|
||||
@ -317,6 +328,15 @@ void SpekSpectrogram::start()
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void SpekSpectrogram::stop()
|
||||
{
|
||||
if (this->pipeline) {
|
||||
spek_pipeline_close(this->pipeline);
|
||||
this->pipeline = NULL;
|
||||
this->properties = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Trim `s` so that it fits into `length`.
|
||||
static wxString trim(wxDC& dc, const wxString& s, int length, bool trim_end)
|
||||
{
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <wx/wx.h>
|
||||
|
||||
class SpekHaveSampleEvent;
|
||||
struct spek_audio_properties;
|
||||
struct spek_pipeline;
|
||||
|
||||
@ -28,6 +29,7 @@ class SpekSpectrogram : public wxPanel
|
||||
{
|
||||
public:
|
||||
SpekSpectrogram(wxFrame *parent);
|
||||
~SpekSpectrogram();
|
||||
void open(const wxString& path);
|
||||
void save(const wxString& path);
|
||||
|
||||
@ -35,10 +37,11 @@ private:
|
||||
void on_idle(wxIdleEvent& evt);
|
||||
void on_paint(wxPaintEvent& evt);
|
||||
void on_size(wxSizeEvent& evt);
|
||||
void on_have_sample(SpekHaveSampleEvent& evt);
|
||||
void render(wxDC& dc);
|
||||
|
||||
void start();
|
||||
static void pipeline_cb(int sample, float *values, void *cb_data);
|
||||
void stop();
|
||||
|
||||
spek_pipeline *pipeline;
|
||||
const spek_audio_properties *properties;
|
||||
|
Loading…
x
Reference in New Issue
Block a user