diff --git a/src/cnetz/fsk_demod.c b/src/cnetz/fsk_demod.c index 5996038..3164217 100644 --- a/src/cnetz/fsk_demod.c +++ b/src/cnetz/fsk_demod.c @@ -218,12 +218,12 @@ void fsk_fm_exit(fsk_fm_demod_t *fsk) #endif } -/* get levels, sync time and jitter from sync sequence or frame data */ -static inline void get_levels(fsk_fm_demod_t *fsk, double *_min, double *_max, double *_avg, int *_probes, int num, double *_time, double *_jitter) +/* get levels, sync time and jitter/stddev from sync sequence or frame data */ +static inline void get_levels(fsk_fm_demod_t *fsk, double *_min, double *_max, double *_avg, int *_probes, int num, double *_time, double *_jitter, double *_stddev) { int count = 0; double min = 0, max = 0, avg = 0, level; - double time = 0, t, sync_average, sync_time, jitter = 0; + double time = 0, t, sync_average, sync_time, jitter = 0.0, stddev = 0.0; int bit_offset; int i; @@ -252,6 +252,8 @@ static inline void get_levels(fsk_fm_demod_t *fsk, double *_min, double *_max, d avg += level; count++; } + avg /= (double)count; + time /= (double)count; /* should never happen */ if (!count) { @@ -264,13 +266,13 @@ static inline void get_levels(fsk_fm_demod_t *fsk, double *_min, double *_max, d * late (positive) we received the sync relative to current bit_time. * sync_time is the absolute time within the super frame. */ - sync_average = time / (double)count; + sync_average = time; sync_time = fmod(sync_average + fsk->bit_time + BITS_PER_SUPERFRAME, BITS_PER_SUPERFRAME); *_probes = count; *_min = min; *_max = max; - *_avg = avg / (double)count; + *_avg = avg; if (_time) { // if (fsk->cnetz->dsp_mode == DSP_MODE_SPK_V) @@ -303,6 +305,16 @@ static inline void get_levels(fsk_fm_demod_t *fsk, double *_min, double *_max, d } *_jitter = jitter / (double)count; } + if (_stddev) { + /* get standard deviation of level */ + for (i = 0; i < num; i++) { + level = fsk->change_levels[(fsk->change_pos - 1 - i) & 0xff]; + if (level <= 0.0) + continue; + stddev += (level - avg) * (level - avg); + } + *_stddev = sqrt(stddev / (double)count); + } } static inline void got_bit(fsk_fm_demod_t *fsk, int bit, double change_level) @@ -348,11 +360,11 @@ got_sync: if (debug) fprintf(fsk->debug_fp, " SYNC!"); #endif - get_levels(fsk, &min, &max, &avg, &probes, 30, &fsk->sync_time, &fsk->sync_jitter); + get_levels(fsk, &min, &max, &avg, &probes, 30, &fsk->sync_time, NULL, &fsk->sync_stddev); fsk->sync_level = avg; if (fsk->sync == FSK_SYNC_NEGATIVE) fsk->sync_level = -fsk->sync_level; -// printf("sync (change min=%.0f%% max=%.0f%% avg=%.0f%% sync_time=%.2f jitter=%.2f probes=%d)\n", min * 100, max * 100, avg * 100, fsk->sync_time, fsk->sync_jitter, probes); +// printf("sync (change min=%.0f%% max=%.0f%% avg=%.0f%% sync_time=%.2f stddev=%.0f%% probes=%d)\n", min * 100, max * 100, avg * 100, fsk->sync_time, fsk->sync_stddev / avg, probes); fsk->level_threshold = (double)avg; fsk->rx_sync = 0; fsk->rx_buffer_count = 0; @@ -381,7 +393,8 @@ got_sync: /* received 662 bits after start of block (10 SPK blocks + 1 bit (== 2 level changes)) */ fsk->sync_time = fmod(fsk->sync_time - (66*10+2) + BITS_PER_SUPERFRAME, BITS_PER_SUPERFRAME); } - cnetz_decode_telegramm(fsk->cnetz, fsk->rx_buffer, fsk->sync_level, fsk->sync_time, fsk->sync_jitter); + /* receive frame */ + cnetz_decode_telegramm(fsk->cnetz, fsk->rx_buffer, fsk->sync_level, fsk->sync_time, fsk->sync_stddev); } break; } @@ -457,7 +470,7 @@ static inline void find_change_slope(fsk_fm_demod_t *fsk) fsk->last_change_positive = change_positive; if (!fsk->sync) { fsk->next_bit = 1.5; - got_bit(fsk, change_positive, (level_max - level_min) / 2); + got_bit(fsk, change_positive, (level_max - level_min) / 2.0); } } if (fsk->next_bit <= 0.0) { @@ -530,9 +543,10 @@ static inline void find_change_level(fsk_fm_demod_t *fsk) fsk->last_change_positive = change_positive; if (!fsk->sync) { fsk->next_bit = 1.5; - /* if bit change is inside window, we can get level from end of window */ - s = fsk->bit_buffer_spl[(fsk->bit_buffer_pos + fsk->bit_buffer_len - 1) % fsk->bit_buffer_len]; - got_bit(fsk, change_positive, fabs(s)); + /* if bit change is inside window, we can get level from borders of window */ + s = fsk->bit_buffer_spl[fsk->bit_buffer_pos]; + s -= fsk->bit_buffer_spl[(fsk->bit_buffer_pos + fsk->bit_buffer_len - 1) % fsk->bit_buffer_len]; + got_bit(fsk, change_positive, fabs(s / 2.0)); } } if (fsk->next_bit <= 0.0) { diff --git a/src/cnetz/fsk_demod.h b/src/cnetz/fsk_demod.h index 3410268..addce17 100644 --- a/src/cnetz/fsk_demod.h +++ b/src/cnetz/fsk_demod.h @@ -39,7 +39,7 @@ typedef struct fsk_fm_demod { enum fsk_sync sync; /* set, if we are in sync and what polarity we receive */ double sync_level; /* what was the level, when we received the sync */ double sync_time; /* when did we receive sync, relative to super frame */ - double sync_jitter; /* what was the jitter of the sync */ + double sync_stddev; /* standard deviation of level changes */ /* speech */ sample_t *speech_buffer; /* holds one chunk of 12.5ms */ diff --git a/src/cnetz/telegramm.c b/src/cnetz/telegramm.c index 6c77af2..8b0b539 100644 --- a/src/cnetz/telegramm.c +++ b/src/cnetz/telegramm.c @@ -1462,7 +1462,7 @@ static const char *deinterleave(const char *input) return output; } -void cnetz_decode_telegramm(cnetz_t *cnetz, const char *bits, double level, double sync_time, double jitter) +void cnetz_decode_telegramm(cnetz_t *cnetz, const char *bits, double level, double sync_time, double stddev) { telegramm_t telegramm; uint8_t opcode; @@ -1489,12 +1489,11 @@ void cnetz_decode_telegramm(cnetz_t *cnetz, const char *bits, double level, doub opcode = telegramm.opcode; telegramm.level = level; telegramm.sync_time = sync_time; - telegramm.jitter = jitter; if (bit_errors) - PDEBUG_CHAN(DDSP, DEBUG_INFO, "RX Level: %.0f%% Jitter: %.2f Sync Time: %.2f (TS %.2f) Bit errors: %d %s\n", fabs(level) / cnetz->fsk_deviation * 100.0, jitter, sync_time, sync_time / 396.0, bit_errors, (level < 0) ? "NEGATIVE (phone's mode)" : "POSITIVE (base station's mode)"); + PDEBUG_CHAN(DDSP, DEBUG_INFO, "RX Level: %.0f%% Standard deviation: %.0f%% Sync Time: %.2f (TS %.2f) Bit errors: %d %s\n", fabs(level) / cnetz->fsk_deviation * 100.0, stddev / fabs(level) * 100.0, sync_time, sync_time / 396.0, bit_errors, (level < 0) ? "NEGATIVE (phone's mode)" : "POSITIVE (base station's mode)"); else - PDEBUG_CHAN(DDSP, DEBUG_INFO, "RX Level: %.0f%% Jitter: %.2f Sync Time: %.2f (TS %.2f) %s\n", fabs(level) / cnetz->fsk_deviation * 100.0, jitter, sync_time, sync_time / 396.0, (level < 0) ? "NEGATIVE (phone's mode)" : "POSITIVE (base station's mode)"); + PDEBUG_CHAN(DDSP, DEBUG_INFO, "RX Level: %.0f%% Standard deviation: %.0f%% Sync Time: %.2f (TS %.2f) %s\n", fabs(level) / cnetz->fsk_deviation * 100.0, stddev / fabs(level) * 100.0, sync_time, sync_time / 396.0, (level < 0) ? "NEGATIVE (phone's mode)" : "POSITIVE (base station's mode)"); if (cnetz->sender.loopback) { PDEBUG(DFRAME, DEBUG_NOTICE, "Received Telegramm in loopback test mode (opcode %d = %s)\n", opcode, definition_opcode[opcode].message_name); diff --git a/src/cnetz/telegramm.h b/src/cnetz/telegramm.h index bd4ffca..b6bb351 100644 --- a/src/cnetz/telegramm.h +++ b/src/cnetz/telegramm.h @@ -61,7 +61,6 @@ typedef struct telegramm { double level; /* average level of received sync sequence */ double sync_time; /* when did we receive the sync for this frame */ - double jitter; /* phase jitter of sync sequence */ uint8_t opcode; /* used parameters depend on opcode */ uint8_t fuz_fuvst_nr; @@ -124,6 +123,6 @@ int match_fuz(cnetz_t *cnetz, telegramm_t *telegramm, int cell); int match_futln(telegramm_t *telegramm, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest); int detect_sync(uint64_t bitstream); -void cnetz_decode_telegramm(cnetz_t *cnetz, const char *bits, double level, double sync_time, double jitter); +void cnetz_decode_telegramm(cnetz_t *cnetz, const char *bits, double level, double sync_time, double stddev); const char *cnetz_encode_telegramm(cnetz_t *cnetz);