mirror of
https://github.com/alexkay/spek.git
synced 2025-04-22 03:10:29 +03:00
parent
a00057b4c8
commit
437dc2fe5b
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
*.a
|
||||
*.core
|
||||
*.exe
|
||||
*.msi
|
||||
*.o
|
||||
|
@ -53,6 +53,9 @@ On OS X use the Command key instead of Ctrl.
|
||||
`Ctrl-Shift-up`, `Ctrl-Shift-down`
|
||||
: Change the upper limit of the dynamic range in dBFS.
|
||||
|
||||
`s`, `S`
|
||||
: Change the DFT window size.
|
||||
|
||||
# FILES
|
||||
|
||||
*~/.config/spek/preferences*
|
||||
|
@ -325,7 +325,7 @@ static void * reader_func(void *pp)
|
||||
pthread_join(p->worker_thread, NULL);
|
||||
|
||||
// Notify the client.
|
||||
p->cb(-1, NULL, p->cb_data);
|
||||
p->cb(p->fft->get_output_size(), -1, NULL, p->cb_data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -422,7 +422,7 @@ static void * worker_func(void *pp)
|
||||
}
|
||||
|
||||
if (sample == p->samples) break;
|
||||
p->cb(sample++, p->output, p->cb_data);
|
||||
p->cb(p->fft->get_output_size(), sample++, p->output, p->cb_data);
|
||||
|
||||
memset(p->output, 0, sizeof(float) * p->fft->get_output_size());
|
||||
frames = 0;
|
||||
|
@ -26,7 +26,7 @@ class AudioFile;
|
||||
class FFTPlan;
|
||||
struct spek_pipeline;
|
||||
|
||||
typedef void (*spek_pipeline_cb)(int sample, float *values, void *cb_data);
|
||||
typedef void (*spek_pipeline_cb)(int bands, int sample, float *values, void *cb_data);
|
||||
|
||||
struct spek_pipeline * spek_pipeline_open(
|
||||
std::unique_ptr<AudioFile> file,
|
||||
|
@ -40,12 +40,13 @@ END_EVENT_TABLE()
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_RANGE = 0,
|
||||
MIN_RANGE = -140,
|
||||
MAX_RANGE = 0,
|
||||
URANGE = -20,
|
||||
LRANGE = -120,
|
||||
FFT_BITS = 11,
|
||||
BANDS = (1 << (FFT_BITS - 1)) + 1,
|
||||
MIN_FFT_BITS = 8,
|
||||
MAX_FFT_BITS = 14,
|
||||
LPAD = 60,
|
||||
TPAD = 60,
|
||||
RPAD = 90,
|
||||
@ -56,6 +57,7 @@ enum
|
||||
|
||||
// Forward declarations.
|
||||
static wxString trim(wxDC& dc, const wxString& s, int length, bool trim_end);
|
||||
static int bits_to_bands(int bits);
|
||||
|
||||
SpekSpectrogram::SpekSpectrogram(wxFrame *parent) :
|
||||
wxWindow(
|
||||
@ -67,25 +69,17 @@ SpekSpectrogram::SpekSpectrogram(wxFrame *parent) :
|
||||
pipeline(NULL),
|
||||
duration(0.0),
|
||||
sample_rate(0),
|
||||
palette(RULER, BANDS),
|
||||
palette(),
|
||||
image(1, 1),
|
||||
prev_width(-1),
|
||||
fft_bits(FFT_BITS),
|
||||
urange(URANGE),
|
||||
lrange(LRANGE)
|
||||
{
|
||||
this->create_palette();
|
||||
|
||||
SetBackgroundStyle(wxBG_STYLE_CUSTOM);
|
||||
SetFocus();
|
||||
|
||||
// Pre-draw the palette.
|
||||
for (int y = 0; y < BANDS; y++) {
|
||||
uint32_t color = spek_palette_spectrum(y / (double) BANDS);
|
||||
this->palette.SetRGB(
|
||||
wxRect(0, BANDS - y - 1, RULER, 1),
|
||||
color >> 16,
|
||||
(color >> 8) & 0xFF,
|
||||
color & 0xFF
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SpekSpectrogram::~SpekSpectrogram()
|
||||
@ -111,19 +105,27 @@ void SpekSpectrogram::save(const wxString& path)
|
||||
|
||||
void SpekSpectrogram::on_char(wxKeyEvent& evt)
|
||||
{
|
||||
bool N = evt.GetModifiers() == wxMOD_NONE;
|
||||
bool C = evt.GetModifiers() == wxMOD_CONTROL;
|
||||
bool S = evt.GetModifiers() == wxMOD_SHIFT;
|
||||
bool CS = evt.GetModifiers() == (wxMOD_CONTROL | wxMOD_SHIFT);
|
||||
bool dn = evt.GetKeyCode() == WXK_DOWN;
|
||||
bool up = evt.GetKeyCode() == WXK_UP;
|
||||
bool U = evt.GetKeyCode() == WXK_UP;
|
||||
bool D = evt.GetKeyCode() == WXK_DOWN;
|
||||
|
||||
if (C && up) {
|
||||
if (C && U) {
|
||||
this->lrange = spek_min(this->lrange + 1, this->urange - 1);
|
||||
} else if (C && dn) {
|
||||
} else if (C && D) {
|
||||
this->lrange = spek_max(this->lrange - 1, MIN_RANGE);
|
||||
} else if (CS && up) {
|
||||
} else if (CS && U) {
|
||||
this->urange = spek_min(this->urange + 1, MAX_RANGE);
|
||||
} else if (CS && dn) {
|
||||
} else if (CS && D) {
|
||||
this->urange = spek_max(this->urange - 1, this->lrange + 1);
|
||||
} else if (S && evt.GetKeyCode() == 'S') {
|
||||
this->fft_bits = spek_min(this->fft_bits + 1, MAX_FFT_BITS);
|
||||
this->create_palette();
|
||||
} else if (N && evt.GetKeyCode() == 's') {
|
||||
this->fft_bits = spek_max(this->fft_bits - 1, MIN_FFT_BITS);
|
||||
this->create_palette();
|
||||
} else {
|
||||
evt.Skip();
|
||||
return;
|
||||
@ -343,9 +345,9 @@ void SpekSpectrogram::render(wxDC& dc)
|
||||
}
|
||||
}
|
||||
|
||||
static void pipeline_cb(int sample, float *values, void *cb_data)
|
||||
static void pipeline_cb(int bands, int sample, float *values, void *cb_data)
|
||||
{
|
||||
SpekHaveSampleEvent event(BANDS, sample, values, false);
|
||||
SpekHaveSampleEvent event(bands, sample, values, false);
|
||||
SpekSpectrogram *s = (SpekSpectrogram *)cb_data;
|
||||
wxPostEvent(s, event);
|
||||
}
|
||||
@ -364,10 +366,10 @@ void SpekSpectrogram::start()
|
||||
wxSize size = GetClientSize();
|
||||
int samples = size.GetWidth() - LPAD - RPAD;
|
||||
if (samples > 0) {
|
||||
this->image.Create(samples, BANDS);
|
||||
this->image.Create(samples, bits_to_bands(this->fft_bits));
|
||||
this->pipeline = spek_pipeline_open(
|
||||
this->audio->open(std::string(this->path.utf8_str())),
|
||||
this->fft->create(FFT_BITS),
|
||||
this->fft->create(this->fft_bits),
|
||||
samples,
|
||||
pipeline_cb,
|
||||
this
|
||||
@ -393,6 +395,20 @@ void SpekSpectrogram::stop()
|
||||
}
|
||||
}
|
||||
|
||||
void SpekSpectrogram::create_palette()
|
||||
{
|
||||
this->palette.Create(RULER, bits_to_bands(this->fft_bits));
|
||||
for (int y = 0; y < bits_to_bands(this->fft_bits); y++) {
|
||||
uint32_t color = spek_palette_spectrum(y / (double)bits_to_bands(this->fft_bits));
|
||||
this->palette.SetRGB(
|
||||
wxRect(0, bits_to_bands(this->fft_bits) - y - 1, RULER, 1),
|
||||
color >> 16,
|
||||
(color >> 8) & 0xFF,
|
||||
color & 0xFF
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Trim `s` so that it fits into `length`.
|
||||
static wxString trim(wxDC& dc, const wxString& s, int length, bool trim_end)
|
||||
{
|
||||
@ -422,3 +438,8 @@ static wxString trim(wxDC& dc, const wxString& s, int length, bool trim_end)
|
||||
|
||||
return trim_end ? s.substr(0, i) + fix : fix + s.substr(k);
|
||||
}
|
||||
|
||||
// TODO: test
|
||||
static int bits_to_bands(int bits) {
|
||||
return (1 << (bits - 1)) + 1;
|
||||
}
|
||||
|
@ -46,6 +46,8 @@ private:
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
void create_palette();
|
||||
|
||||
std::unique_ptr<Audio> audio;
|
||||
std::unique_ptr<FFT> fft;
|
||||
spek_pipeline *pipeline;
|
||||
@ -56,6 +58,7 @@ private:
|
||||
wxImage palette;
|
||||
wxImage image;
|
||||
int prev_width;
|
||||
int fft_bits;
|
||||
int urange;
|
||||
int lrange;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user