Browse Source

C-Netz: Improved RX speech quality and decoder debugging

master
Andreas Eversberg 1 month ago
parent
commit
89e3b89758
  1. 4
      src/cnetz/cnetz.h
  2. 33
      src/cnetz/dsp.c
  3. 58
      src/cnetz/fsk_demod.c

4
src/cnetz/cnetz.h

@ -127,8 +127,8 @@ struct cnetz {
double frame_last_phase; /* master's bit phase of last frame sync */
/* audio offset removal */
double offset_factor; /* filer alpha of high-pass filter */
double offset_y_last; /* last stored sample */
double offset_last; /* last sample value of last frame */
int offset_range; /* range of samples to ramp the offset */
/* measurements */
int measure_speed; /* measure clock speed */

33
src/cnetz/dsp.c

@ -46,7 +46,6 @@
#define MAX_DISPLAY 1.4 /* something above speech level, no emphasis */
#define BITRATE 5280.0 /* bits per second */
#define BLOCK_BITS 198 /* duration of one time slot including pause at beginning and end */
#define CUT_OFF_OFFSET 300.0 /* cut off frequency for offset filter (level correction between subsequent audio chunks) */
#ifdef TEST_SCRAMBLE
jitter_t scrambler_test_jb;
@ -103,7 +102,6 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], en
{
int rc = 0;
double size;
double RC, dt;
PDEBUG_CHAN(DDSP, DEBUG_DEBUG, "Init FSK for 'Sender'.\n");
@ -150,7 +148,7 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], en
}
/* reinit the sample rate to shrink/expand audio */
init_samplerate(&cnetz->sender.srstate, 8000.0, (double)cnetz->sender.samplerate / 1.1, 3300.0); /* 66 <-> 60 */
init_samplerate(&cnetz->sender.srstate, 8000.0, (double)cnetz->sender.samplerate / (1.1 / (1.0 + clock_speed[0] / 1000000.0)), 3300.0); /* 66 <-> 60 */
rc = fsk_fm_init(&cnetz->fsk_demod, cnetz, cnetz->sender.samplerate, (double)BITRATE / (1.0 + clock_speed[0] / 1000000.0), demod);
if (rc < 0)
@ -170,10 +168,8 @@ int dsp_init_sender(cnetz_t *cnetz, int measure_speed, double clock_speed[2], en
* shall not exceed according to ITU G.162 */
init_compandor(&cnetz->cstate, 8000, 5.0, 22.5);
/* use this filter to compensate level changes between two subsequent audio chunks */
RC = 1.0 / (CUT_OFF_OFFSET * 2.0 *3.14);
dt = 1.0 / cnetz->sender.samplerate;
cnetz->offset_factor = RC / (RC + dt);
/* use duration of one bit to ramp level of last frame to current frame */
cnetz->offset_range = ceil(cnetz->fsk_bitduration);
#ifdef TEST_SCRAMBLE
rc = jitter_create(&scrambler_test_jb, cnetz->sender.samplerate / 5);
@ -821,7 +817,8 @@ void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count)
{
sample_t *spl;
int pos, i;
double x, y, x_last, y_last, factor;
int range;
double offset;
/* check if we still have a transaction
* this might not be true, if we just released transaction, but still
@ -830,21 +827,13 @@ void unshrink_speech(cnetz_t *cnetz, sample_t *speech_buffer, int count)
if (!cnetz->trans_list)
return;
/* fix offset between speech blocks by using high pass filter */
/* use first sample as previous sample, so we don't have a level jump between two subsequent audio chunks */
x_last = speech_buffer[0];
y_last = cnetz->offset_y_last;
factor = cnetz->offset_factor;
for (i = 0; i < count; i++) {
/* change level */
x = speech_buffer[i];
/* high-pass to remove low level frequencies, caused by level jump between audio chunks */
y = factor * (y_last + x - x_last);
x_last = x;
y_last = y;
speech_buffer[i] = y;
/* ramp from level of last frame to level of current frame */
range = cnetz->offset_range;
offset = speech_buffer[0] - cnetz->offset_last;
for (i = 0; i < range; i++) {
speech_buffer[i] -= offset * (1.0 - (double)i / (double)range);
}
cnetz->offset_y_last = y_last;
cnetz->offset_last = speech_buffer[count - 1];
/* 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 */

58
src/cnetz/fsk_demod.c

@ -121,7 +121,10 @@
* if debug is set to 1, debugging will start at program start
*/
//#define DEBUG_DECODER
//static int debug = 0;
#ifdef DEBUG_DECODER
static int debug = 0;
#endif
#include <stdio.h>
#include <stdint.h>
@ -182,7 +185,7 @@ int fsk_fm_init(fsk_fm_demod_t *fsk, cnetz_t *cnetz, int samplerate, double bitr
#ifdef DEBUG_DECODER
char debug_filename[256];
sprintf(debug_filename, "/tmp/debug_decoder_channel_%d.txt", cnetz->sender.kanal);
sprintf(debug_filename, "/tmp/debug_decoder_channel_%s.txt", cnetz->sender.kanal);
fsk->debug_fp = fopen(debug_filename, "w");
if (!fsk->debug_fp) {
fprintf(stderr, "Failed to open decoder debug file '%s'!\n", debug_filename);
@ -414,17 +417,6 @@ static inline void find_change_slope(fsk_fm_demod_t *fsk)
sample_t threshold;
int i;
#ifdef DEBUG_DECODER
/* show deviation of middle sample in windows (in a range of bandwidth) */
if (debug) {
fprintf(fsk->debug_fp, "%s",
debug_amplitude(
fsk->bit_buffer_spl[(fsk->bit_buffer_pos + fsk->bit_buffer_half) % fsk->bit_buffer_len]
)
);
}
#endif
/* get level range (level_min and level_max) and also
* get maximum slope (change_max) and where it was
* (change_at) and what direction it went (change_positive)
@ -492,10 +484,6 @@ static inline void find_change_slope(fsk_fm_demod_t *fsk)
}
fsk->next_bit -= fsk->bits_per_sample;
#ifdef DEBUG_DECODER
if (debug)
fprintf(fsk->debug_fp, "\n");
#endif
}
/* find bit change by looking at zero crossing */
@ -507,12 +495,6 @@ static inline void find_change_level(fsk_fm_demod_t *fsk)
/* get bit in the middle of the buffer */
s = fsk->bit_buffer_spl[(fsk->bit_buffer_pos + fsk->bit_buffer_half) % fsk->bit_buffer_len];
#ifdef DEBUG_DECODER
/* show deviation */
if (debug)
fprintf(fsk->debug_fp, "%s", debug_amplitude(s));
#endif
/* just sample first bit in distributed mode */
if (fsk->cnetz->dsp_mode == DSP_MODE_SPK_V && fsk->bit_count == 0) {
if (fmod(fsk->bit_time, BITS_PER_SPK_BLOCK) < 1.5)
@ -569,10 +551,6 @@ static inline void find_change_level(fsk_fm_demod_t *fsk)
fsk->next_bit -= fsk->bits_per_sample;
done:
#ifdef DEBUG_DECODER
if (debug)
fprintf(fsk->debug_fp, "\n");
#endif
return;
}
@ -580,7 +558,7 @@ done:
void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length)
{
int i;
double t;
double t = 0.0;
/* process signaling block, sample by sample */
for (i = 0; i < length; i++) {
@ -590,6 +568,14 @@ void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length)
if (fsk->bit_buffer_pos == fsk->bit_buffer_len)
fsk->bit_buffer_pos = 0;
#ifdef DEBUG_DECODER
/* show deviation of center sample in window */
if (debug)
fprintf(fsk->debug_fp, "%s", debug_amplitude(fsk->bit_buffer_spl[(fsk->bit_buffer_pos + fsk->bit_buffer_half) % fsk->bit_buffer_len]));
if (debug && fmod(fsk->bit_time - fsk->bits_per_sample, 1.0) > fmod(fsk->bit_time, 1.0))
fprintf(fsk->debug_fp, " -bitchange-");
#endif
/* for each sample process buffer */
if (fsk->cnetz->dsp_mode != DSP_MODE_SPK_V) {
if (fsk->demod_type == FSK_DEMOD_SLOPE)
@ -611,7 +597,7 @@ void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length)
fsk->next_bit = 1.0 - fsk->bits_per_sample;
#ifdef DEBUG_DECODER
if (debug && fsk->bit_count)
fprintf(fsk->debug_fp, "---- SPK(V) BLOCK START ----\n");
fprintf(fsk->debug_fp, "\n---- SPK(V) BLOCK START ----");
#endif
fsk->bit_count = 0;
} else
@ -622,13 +608,21 @@ void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length)
find_change_level(fsk);
} else
if (t >= 5.5 && t < 65.5) {
#ifdef DEBUG_DECODER
if (debug && !fsk->speech_count)
fprintf(fsk->debug_fp, " (start recording speech)");
#endif
/* get audio for the duration of 60 bits */
/* prevent overflow, if speech_size != 0 and SPK_V
* has been restarted. */
if (fsk->speech_count < fsk->speech_size)
fsk->speech_buffer[fsk->speech_count++] = samples[i];
fsk->speech_buffer[fsk->speech_count++] = fsk->bit_buffer_spl[(fsk->bit_buffer_pos + fsk->bit_buffer_half) % fsk->bit_buffer_len];
} else
if (t >= 65.5) {
#ifdef DEBUG_DECODER
if (debug && fsk->speech_count)
fprintf(fsk->debug_fp, " (stop recording speech)");
#endif
if (fsk->speech_count) {
unshrink_speech(fsk->cnetz, fsk->speech_buffer, fsk->speech_count);
fsk->speech_count = 0;
@ -641,6 +635,10 @@ void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length)
if (fsk->bit_time >= BITS_PER_SUPERFRAME) {
fsk->bit_time -= BITS_PER_SUPERFRAME;
}
#ifdef DEBUG_DECODER
if (debug && samples)
fprintf(fsk->debug_fp, "\n");
#endif
/* another clock is used to measure actual super frame time */
fsk->bit_time_uncorrected += fsk->bits_per_sample;
if (fsk->bit_time_uncorrected >= BITS_PER_SUPERFRAME) {

Loading…
Cancel
Save