Skip to content

Commit

Permalink
Adjust normalisation and scaling
Browse files Browse the repository at this point in the history
  • Loading branch information
ryansuchocki committed Dec 22, 2022
1 parent daac228 commit c16d415
Show file tree
Hide file tree
Showing 12 changed files with 45 additions and 40 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ override CFLAGS += -isystem third_party -I src -std=gnu2x \
-Wnull-dereference -Wvector-operation-performance -Wformat-signedness \
-Wwrite-strings -Wlogical-op -Wjump-misses-init -Wcast-align \
-Wconversion -Wsign-conversion \
-Wdouble-promotion -Wfloat-conversion -Wfloat-equal \
-fanalyzer
-Wdouble-promotion -Wfloat-conversion -Wfloat-equal #\
# -fanalyzer

override LDFLAGS += -lm -lasound -lfftw3

Expand Down
4 changes: 4 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ static CONFIG_T defaults = {
.capture_gain = 1,
.dc_alpha = 0.999,
.x_window = false,
.dbm_cal = 0,
.refl = 0,
.refh = 20,
.ref_interval = 1,
.sgam_spread = 1,
.sgam_drag = 0.9,
.wfall_zoom = 5,
Expand Down Expand Up @@ -64,8 +66,10 @@ struct
{"capture_gain", DOUBLE, .DOUBLE = &config.capture_gain},
{"dc_alpha", DOUBLE, .DOUBLE = &config.dc_alpha},
{"x_window", BOOL, .BOOL = &config.x_window},
{"dbm_cal", DOUBLE, .DOUBLE = &config.dbm_cal},
{"refl", DOUBLE, .DOUBLE = &config.refl},
{"refh", DOUBLE, .DOUBLE = &config.refh},
{"ref_interval", UINT, .UINT = &config.ref_interval},
{"sgam_spread", UINT, .UINT = &config.sgam_spread},
{"sgam_drag", DOUBLE, .DOUBLE = &config.sgam_drag},
{"wfall_zoom", UINT, .UINT = &config.wfall_zoom},
Expand Down
2 changes: 2 additions & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ typedef struct
double capture_gain;
double dc_alpha;
bool x_window;
double dbm_cal;
double refl;
double refh;
unsigned ref_interval;
unsigned sgam_spread;
double sgam_drag;
unsigned wfall_zoom;
Expand Down
2 changes: 1 addition & 1 deletion src/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@
void display_open(unsigned sample_rate);
void display_close(void);
void display_update_bg(unsigned sample_rate);
void display_update(double *amplitudes);
void display_update(const double *dbm_values);
6 changes: 3 additions & 3 deletions src/display/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,10 @@ void render_debug_line(void)
render_text(fb.buf, debug_line, -7, -10, false, YELLOW);
}

void display_update(double *amplitudes)
void display_update(const double *dbm_values)
{
spectrogram_update(amplitudes);
waterfall_update(amplitudes);
spectrogram_update(dbm_values);
waterfall_update(dbm_values);

static int64_t next_frame_due = 0;

Expand Down
17 changes: 10 additions & 7 deletions src/display/spectrogram.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ void spectrogram_render_bg(fb_buf_t *bg)
}

// Horizontal reference lines
for (int y = (int)(floor(config.refl + 1)); y < config.refh; y++)
int start = (int)(floor(config.refl / config.ref_interval + 1)) * (int)config.ref_interval;
int stop = (int)ceil(config.refh);

for (int y = start; y < stop; y += (int)config.ref_interval)
{
int yyy = (int)((y - config.refl) * SGAM_HEIGHT / (config.refh - config.refl));
for (int x = 8 + 8 + 8 + 1; (x + 3) < SGAM_WIDTH; x += 8)
Expand All @@ -58,19 +61,19 @@ void spectrogram_render_bg(fb_buf_t *bg)
}
}

void spectrogram_update(const double *values)
void spectrogram_update(const double *dbm_values)
{
double sum = 0;
for (unsigned i = 0; i < config.sgam_spread * 2; i++)
{
sum += values[i];
sum += dbm_values[i];
}

for (unsigned i = config.sgam_spread; i < SGAM_WIDTH - config.sgam_spread; i++)
{
sum += values[i + config.sgam_spread];
sum += dbm_values[i + config.sgam_spread];
double this_amplitude = sum / (config.sgam_spread * 2 + 1);
sum -= values[i - config.sgam_spread];
sum -= dbm_values[i - config.sgam_spread];

smoothed_values[i] = smoothed_values[i] * config.sgam_drag;
smoothed_values[i] += this_amplitude * (1.0 - config.sgam_drag);
Expand All @@ -84,9 +87,9 @@ void render_spectrogram(fb_buf_t *buf)
{
int col = SGAM_LEFT + x;

int amp = (int)(smoothed_values[x] * SGAM_HEIGHT);
double dbm_display = (smoothed_values[x] - config.refl) / (config.refh - config.refl);
int amp = (int)(dbm_display * SGAM_HEIGHT);

// amp *= 0.244140625 * SGAM_HEIGHT;
EQMAX(amp, 0);
EQMIN(amp, SGAM_HEIGHT);

Expand Down
2 changes: 1 addition & 1 deletion src/display/spectrogram.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@
******************************************************************************/

extern void spectrogram_render_bg(fb_buf_t *bg);
extern void spectrogram_update(const double *values);
extern void spectrogram_update(const double *dbm_values);
extern void render_spectrogram(fb_buf_t *buf);
5 changes: 3 additions & 2 deletions src/display/waterfall.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void waterfall_init(void)
}
}

void waterfall_update(const double *values)
void waterfall_update(const double *dbm_values)
{
static unsigned phase = 0;

Expand All @@ -52,7 +52,8 @@ void waterfall_update(const double *values)

for (unsigned x = 0; x < WFALL_WIDTH; x++)
{
int intens = (int)(values[x] * INTENS_LEVELS);
double dbm_display = (dbm_values[x] - config.refl) / (config.refh - config.refl);
int intens = (int)(dbm_display * INTENS_LEVELS);
EQMAX(intens, 0);
waterfall[waterfall_i][x] =
(intens >= INTENS_LEVELS) ? WHITE : wf_map[intens];
Expand Down
2 changes: 1 addition & 1 deletion src/display/waterfall.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@
******************************************************************************/

extern void waterfall_init(void);
extern void waterfall_update(const double *values);
extern void waterfall_update(const double *dbm_values);
extern void render_waterfall(fb_buf_t *buf);
25 changes: 10 additions & 15 deletions src/dsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ static double normalisation_db = 0;
* Code
******************************************************************************/

void dsp_init(unsigned init_fft_size)
void dsp_init(unsigned init_fft_size, unsigned input_scale)
{
fft_size = init_fft_size;
normalisation_db = 10 * log10(INT16_MAX * fft_size);
normalisation_db = 20 * log10(input_scale * fft_size);

fft_in = fftw_alloc_complex(fft_size);
fft_out = fftw_alloc_complex(fft_size);

Expand All @@ -52,12 +53,12 @@ void dsp_free(void)
fftw_free(fft_out);
}

void dsp_process(const complex double *samples, double *results)
void dsp_process(const complex double *iq_inputs, double *dbm_results)
{
// Prepare the samples for processing by FFTW:
for (unsigned i = 0; i < fft_size; i++)
{
complex double sample = samples[i];
complex double sample = iq_inputs[i];

// Apply any configured input gain:
sample *= config.capture_gain;
Expand All @@ -78,23 +79,17 @@ void dsp_process(const complex double *samples, double *results)
unsigned idx = ((fft_size / 2) + i) % fft_size;

// Calculate the magnitude squared of the complex frequency bin
// There's no point performing an expensive square root as it's
// There's no point performing an expensive square root as it's
// just a factor of two after the upcoming log().
double mag_sq = SQUARED(creal(fft_out[idx])) + SQUARED(cimag(fft_out[idx]));

// Convert to dB and compensate for the missing square root
double db = (10 / 2) * log10(mag_sq);
double db = (20 / 2) * log10(mag_sq);

// Normalize for the fft size and the scale of the original integer samples
double dbfs = db - normalisation_db; // 10 * log10(INT16_MAX * fft_size);

// Shift and scale the result using the configured upper and lower reference
// values:
dbfs -= config.refl;
dbfs /= (config.refh - config.refl);
double db_fs = db - normalisation_db; // 20 * log10(input_scale * fft_size);

// Clip out any negative results at this stage to simplify downstream
// processing:
results[i] = MAX(dbfs, 0);
// Convert to dBm using the configured offset:
dbm_results[i] = db_fs + config.dbm_cal;
}
}
4 changes: 2 additions & 2 deletions src/dsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
* API
******************************************************************************/

extern void dsp_init(unsigned init_fft_size);
extern void dsp_init(unsigned init_fft_size, unsigned input_scale);
extern void dsp_free(void);
extern void dsp_process(const complex double *samples, double *results);
extern void dsp_process(const complex double *iq_inputs, double *dbm_results);
12 changes: 6 additions & 6 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ int main(int argc, const char *argv[])

config_init();
sample_rate = config.sample_rate;
dsp_init(FFT_SIZE);
dsp_init(FFT_SIZE, INT16_MAX);

display_open(sample_rate);

Expand All @@ -61,13 +61,13 @@ int main(int argc, const char *argv[])

while (should_run)
{
static complex double samples[FFT_SIZE];
capture.get(samples, FFT_SIZE);
static complex double iq_samples[FFT_SIZE];
capture.get(iq_samples, FFT_SIZE);

static double amplitudes[FFT_SIZE];
dsp_process(samples, amplitudes);
static double dbm_values[FFT_SIZE];
dsp_process(iq_samples, dbm_values);

display_update(amplitudes);
display_update(dbm_values);

if (config_update())
{
Expand Down

0 comments on commit c16d415

Please sign in to comment.