From bd7ccc5fa05587606757adbacb6e1bf12f12fd2c Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sat, 28 Jan 2017 18:18:44 +0100 Subject: [PATCH] Add global DC-Filter and remove all individual DC-Filters --- src/amps/amps.c | 2 +- src/amps/dsp.c | 35 +++++------------------------------ src/amps/dsp.h | 2 +- src/cnetz/dsp.c | 2 ++ src/common/emphasis.c | 10 +++++++--- src/common/emphasis.h | 1 + src/common/goertzel.c | 29 +++++++++-------------------- src/common/sender.c | 8 +++++--- src/test/test_emphasis.c | 1 + 9 files changed, 32 insertions(+), 58 deletions(-) diff --git a/src/amps/amps.c b/src/amps/amps.c index d600b4b..133666f 100644 --- a/src/amps/amps.c +++ b/src/amps/amps.c @@ -450,7 +450,7 @@ int amps_create(int channel, enum amps_chan_type chan_type, const char *audiodev } /* init audio processing */ - rc = dsp_init_sender(amps, (de_emphasis == 0), tolerant); + rc = dsp_init_sender(amps, tolerant); if (rc < 0) { PDEBUG(DAMPS, DEBUG_ERROR, "Failed to init audio processing!\n"); goto error; diff --git a/src/amps/dsp.c b/src/amps/dsp.c index 9c6dc2e..cf359d1 100644 --- a/src/amps/dsp.c +++ b/src/amps/dsp.c @@ -178,12 +178,11 @@ static void dsp_init_ramp(amps_t *amps) static void sat_reset(amps_t *amps, const char *reason); /* Init FSK of transceiver */ -int dsp_init_sender(amps_t *amps, int high_pass, int tolerant) +int dsp_init_sender(amps_t *amps, int tolerant) { sample_t *spl; int i; int rc; - double RC, dt; int half; /* attack (3ms) and recovery time (13.5ms) according to amps specs */ @@ -256,14 +255,6 @@ int dsp_init_sender(amps_t *amps, int high_pass, int tolerant) amps->test_phaseshift256 = 256.0 / ((double)amps->sender.samplerate / 1000.0); PDEBUG(DDSP, DEBUG_DEBUG, "test_phaseshift256 = %.4f\n", amps->test_phaseshift256); - /* use this filter to remove dc level for 0-crossing detection - * if we have de-emphasis, we don't need it, so high_pass is not set. */ - if (high_pass) { - RC = 1.0 / (CUT_OFF_HIGHPASS * 2.0 *3.14); - dt = 1.0 / amps->sender.samplerate; - amps->highpass_factor = RC / (RC + dt); - } - /* be more tolerant when syncing */ amps->fsk_rx_sync_tolerant = tolerant; @@ -808,8 +799,7 @@ static void sender_receive_audio(amps_t *amps, sample_t *samples, int length) int max, pos; int i; - /* SAT detection */ - + /* SAT / signalling tone detection */ max = amps->sat_samples; spl = amps->sat_filter_spl; pos = amps->sat_filter_pos; @@ -853,25 +843,10 @@ static void sender_receive_audio(amps_t *amps, sample_t *samples, int length) void sender_receive(sender_t *sender, sample_t *samples, int length) { amps_t *amps = (amps_t *) sender; - double x, y, x_last, y_last, factor; - int i; - /* high pass filter to remove 0-level - * if factor is not set, we should already have 0-level. */ - factor = amps->highpass_factor; - if (factor) { - x_last = amps->highpass_x_last; - y_last = amps->highpass_y_last; - for (i = 0; i < length; i++) { - x = (double)samples[i]; - y = factor * (y_last + x - x_last); - x_last = x; - y_last = y; - samples[i] = y; - } - amps->highpass_x_last = x_last; - amps->highpass_y_last = y_last; - } + /* dc filter required for FSK decoding and tone detection */ + if (amps->de_emphasis) + dc_filter(&s->estate, samples, length); switch (amps->dsp_mode) { case DSP_MODE_OFF: diff --git a/src/amps/dsp.h b/src/amps/dsp.h index 885df65..4dcbac2 100644 --- a/src/amps/dsp.h +++ b/src/amps/dsp.h @@ -1,6 +1,6 @@ void dsp_init(void); -int dsp_init_sender(amps_t *amps, int high_pass, int tolerant); +int dsp_init_sender(amps_t *amps, int tolerant); void dsp_cleanup_sender(amps_t *amps); void amps_set_dsp_mode(amps_t *amps, enum dsp_mode mode, int frame_length); diff --git a/src/cnetz/dsp.c b/src/cnetz/dsp.c index d104e13..a927c55 100644 --- a/src/cnetz/dsp.c +++ b/src/cnetz/dsp.c @@ -812,6 +812,8 @@ void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count) /* 4. de-emphasis is done by cnetz code, not by common code */ /* de-emphasis is only used when scrambler is off, see FTZ 171 TR 60 Clause 4 */ + if (cnetz->de_emphasis) + dc_filter(&cnetz->estate, speech_buffer, count); if (cnetz->de_emphasis && !cnetz->scrambler) de_emphasis(&cnetz->estate, speech_buffer, count); /* 3. descramble */ diff --git a/src/common/emphasis.c b/src/common/emphasis.c index 93c2b6f..524c37b 100644 --- a/src/common/emphasis.c +++ b/src/common/emphasis.c @@ -27,7 +27,7 @@ #define PI M_PI -#define CUT_OFF_H 300.0 /* cut-off frequency for high-pass filters */ +#define CUT_OFF_H 100.0 /* cut-off frequency for high-pass filter */ static void gen_sine(double *samples, int num, int samplerate, double freq) { @@ -106,8 +106,6 @@ void de_emphasis(emphasis_t *state, double *samples, int num) double x, y, y_last, factor, amp; int i; - filter_process(&state->d.hp, samples, num); - y_last = state->d.y_last; factor = state->d.factor; amp = state->d.amp; @@ -126,3 +124,9 @@ void de_emphasis(emphasis_t *state, double *samples, int num) state->d.y_last = y_last; } +/* high pass filter to remove DC and low frequencies */ +void dc_filter(emphasis_t *state, double *samples, int num) +{ + filter_process(&state->d.hp, samples, num); +} + diff --git a/src/common/emphasis.h b/src/common/emphasis.h index 53450d8..f14afd1 100644 --- a/src/common/emphasis.h +++ b/src/common/emphasis.h @@ -17,4 +17,5 @@ typedef struct emphasis { int init_emphasis(emphasis_t *state, int samplerate, double cut_off); void pre_emphasis(emphasis_t *state, double *samples, int num); void de_emphasis(emphasis_t *state, double *samples, int num); +void dc_filter(emphasis_t *state, double *samples, int num); diff --git a/src/common/goertzel.c b/src/common/goertzel.c index eaa7f99..ccfbd12 100644 --- a/src/common/goertzel.c +++ b/src/common/goertzel.c @@ -30,30 +30,26 @@ * audio level calculation */ -/* return average value (rectified value), that can be 0..1 */ +/* Return average value (rectified value) + * The input must not have any dc offset! + * For a perfect rectangualr wave, the result would equal the peak level. + * For a sine wave the result would be factor (2 / PI) below peak level. + */ double audio_level(sample_t *samples, int length) { - double bias; - double level; - int sk; + double level, sk; int n; - /* calculate bias */ - bias = 0; - for (n = 0; n < length; n++) - bias += samples[n]; - bias = bias / length; - /* level calculation */ level = 0; for (n = 0; n < length; n++) { - sk = samples[n] - bias; + sk = samples[n]; if (sk < 0) level -= (double)sk; if (sk > 0) level += (double)sk; } - level = level / (double)length / 32767.0; + level = level / (double)length; return level; } @@ -79,17 +75,10 @@ void audio_goertzel_init(goertzel_t *goertzel, double freq, int samplerate) */ void audio_goertzel(goertzel_t *goertzel, sample_t *samples, int length, int offset, double *result, int k) { - double bias; double sk, sk1, sk2; double cos2pik; int i, n; - /* calculate bias to remove DC */ - bias = 0; - for (n = 0; n < length; n++) - bias += samples[n]; - bias = bias / length; - /* we do goertzel */ for (i = 0; i < k; i++) { sk = 0; @@ -98,7 +87,7 @@ void audio_goertzel(goertzel_t *goertzel, sample_t *samples, int length, int off cos2pik = goertzel[i].coeff; /* note: after 'length' cycles, offset is restored to its initial value */ for (n = 0; n < length; n++) { - sk = (cos2pik * sk1) - sk2 + samples[offset++] - bias; + sk = (cos2pik * sk1) - sk2 + samples[offset++]; sk2 = sk1; sk1 = sk; if (offset == length) diff --git a/src/common/sender.c b/src/common/sender.c index f63e021..62eec06 100644 --- a/src/common/sender.c +++ b/src/common/sender.c @@ -281,7 +281,7 @@ cant_recover: display_wave(inst, samples[i], count); sender_receive(inst, samples[i], count); } - /* do pre emphasis towards radio, not wave_write */ + /* do pre emphasis towards radio */ if (inst->pre_emphasis) pre_emphasis(&inst->estate, samples[i], count); /* set paging signal */ @@ -331,9 +331,11 @@ transmit_later: /* rx gain */ if (inst->rx_gain != 1.0) gain_samples(samples[i], count, inst->rx_gain); - /* do de emphasis from radio (then write_wave/wave_read), receive audio, process echo test */ - if (inst->de_emphasis) + /* do filter and de-emphasis from radio receive audio, process echo test */ + if (inst->de_emphasis) { + dc_filter(&inst->estate, samples[i], count); de_emphasis(&inst->estate, samples[i], count); + } if (inst->loopback != 1) { display_wave(inst, samples[i], count); sender_receive(inst, samples[i], count); diff --git a/src/test/test_emphasis.c b/src/test/test_emphasis.c index c5fa1af..4d79bc2 100644 --- a/src/test/test_emphasis.c +++ b/src/test/test_emphasis.c @@ -64,6 +64,7 @@ int main(void) for (i = 31.25; i < 4001; i = i * sqrt(sqrt(2.0))) { gen_samples(samples, (double)i); + dc_filter(&estate, samples, SAMPLERATE); de_emphasis(&estate, samples, SAMPLERATE); level = get_level(samples); printf("%s%.0f Hz: %.1f dB", debug_db(level), i, level2db(level));