spek

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

commit c6dc7afcea9a7909ae03f038942ce986541ff56b
parent ce6496cbb40b2cee65737079d195f20ac5b2b6a1
Author: Alexander Kojevnikov <alexander@kojevnikov.com>
Date:   Tue, 18 Sep 2012 22:35:34 -0700

Fix a bug in the spectral density clipping

Diffstat:
Mlib/spek-fft.c | 6++----
Mlib/spek-fft.h | 3+--
Mlib/spek-pipeline.c | 6++----
Mlib/spek-pipeline.h | 2+-
Msrc/spek-spectrogram.cc | 9+++++----
5 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/lib/spek-fft.c b/lib/spek-fft.c @@ -22,12 +22,11 @@ #include "spek-fft.h" -struct spek_fft_plan * spek_fft_plan_new(int n, int threshold) +struct spek_fft_plan * spek_fft_plan_new(int n) { struct spek_fft_plan *p = malloc(sizeof(struct spek_fft_plan)); p->input = av_mallocz(sizeof(float) * n); p->output = av_mallocz(sizeof(float) * (n / 2 + 1)); - p->threshold = threshold; int bits = 0; while (n) { n >>= 1; @@ -51,8 +50,7 @@ void spek_fft_execute(struct spek_fft_plan *p) p->input[i * 2] * p->input[i * 2] + p->input[i * 2 + 1] * p->input[i * 2 + 1]; val /= n * n; - val = 10.0 * log10f (val); - p->output[i] = val < p->threshold ? p->threshold : val; + p->output[i] = 10.0 * log10f (val); } } diff --git a/lib/spek-fft.h b/lib/spek-fft.h @@ -26,7 +26,6 @@ struct spek_fft_plan // Internal data. struct RDFTContext *cx; int n; - int threshold; // Exposed properties. float *input; @@ -34,7 +33,7 @@ struct spek_fft_plan }; // Allocate buffers and create a new FFT plan. -struct spek_fft_plan * spek_fft_plan_new(int n, int threshold); +struct spek_fft_plan * spek_fft_plan_new(int n); // Execute the FFT on plan->input. void spek_fft_execute(struct spek_fft_plan *p); diff --git a/lib/spek-pipeline.c b/lib/spek-pipeline.c @@ -45,7 +45,6 @@ struct spek_pipeline const struct spek_audio_properties *properties; int bands; int samples; - int threshold; spek_pipeline_cb cb; void *cb_data; @@ -80,14 +79,13 @@ static void reader_sync(struct spek_pipeline *p, int pos); static float average_input(const struct spek_pipeline *p, void *buffer); struct spek_pipeline * spek_pipeline_open( - const char *path, int bands, int samples, int threshold, spek_pipeline_cb cb, void *cb_data) + const char *path, int bands, int samples, spek_pipeline_cb cb, void *cb_data) { struct spek_pipeline *p = malloc(sizeof(struct spek_pipeline)); p->cx = spek_audio_open(path); p->properties = spek_audio_get_properties(p->cx); p->bands = bands; p->samples = samples; - p->threshold = threshold; p->cb = cb; p->cb_data = cb_data; @@ -109,7 +107,7 @@ struct spek_pipeline * spek_pipeline_open( for (int i = 0; i < p->nfft; ++i) { p->coss[i] = cosf(cf * i); } - p->fft = spek_fft_plan_new(p->nfft, threshold); + p->fft = spek_fft_plan_new(p->nfft); p->input_size = p->nfft * (NFFT * 2 + 1); p->input = malloc(p->input_size * sizeof(float)); p->output = malloc(bands * sizeof(float)); diff --git a/lib/spek-pipeline.h b/lib/spek-pipeline.h @@ -25,7 +25,7 @@ struct spek_audio_properties; typedef void (*spek_pipeline_cb)(int sample, float *values, void *cb_data); struct spek_pipeline * spek_pipeline_open( - const char *path, int bands, int samples, int threshold, spek_pipeline_cb cb, void *cb_data); + const char *path, int bands, int samples, spek_pipeline_cb cb, void *cb_data); const struct spek_audio_properties * spek_pipeline_properties(struct spek_pipeline *pipeline); diff --git a/src/spek-spectrogram.cc b/src/spek-spectrogram.cc @@ -17,6 +17,8 @@ */ #include <cmath> +#include <sys/param.h> + #include <wx/dcbuffer.h> extern "C" { @@ -143,7 +145,6 @@ 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(); @@ -154,9 +155,10 @@ void SpekSpectrogram::on_have_sample(SpekHaveSampleEvent& event) } // TODO: check image size, quit if wrong. + double range = log(1.0 - THRESHOLD); for (int y = 0; y < bands; y++) { - double level = log10(1.0 - THRESHOLD + values[y]) / log10_threshold; - if (level > 1.0) level = 1.0; + double value = MAX(THRESHOLD, values[y]); + double level = log(1.0 - THRESHOLD + value) / range; uint32_t color = spek_palette_spectrum(level); this->image.SetRGB( sample, @@ -353,7 +355,6 @@ void SpekSpectrogram::start() this->path.utf8_str(), BANDS, samples, - THRESHOLD, pipeline_cb, this );