C-Netz: Show standard deviation of bit levels instead of jitter
This commit is contained in:
parent
5ea48588e5
commit
3f2f0fdd8c
|
@ -218,12 +218,12 @@ void fsk_fm_exit(fsk_fm_demod_t *fsk)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get levels, sync time and jitter from sync sequence or frame data */
|
/* 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)
|
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;
|
int count = 0;
|
||||||
double min = 0, max = 0, avg = 0, level;
|
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 bit_offset;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -252,6 +252,8 @@ static inline void get_levels(fsk_fm_demod_t *fsk, double *_min, double *_max, d
|
||||||
avg += level;
|
avg += level;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
avg /= (double)count;
|
||||||
|
time /= (double)count;
|
||||||
|
|
||||||
/* should never happen */
|
/* should never happen */
|
||||||
if (!count) {
|
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.
|
* late (positive) we received the sync relative to current bit_time.
|
||||||
* sync_time is the absolute time within the super frame.
|
* 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);
|
sync_time = fmod(sync_average + fsk->bit_time + BITS_PER_SUPERFRAME, BITS_PER_SUPERFRAME);
|
||||||
|
|
||||||
*_probes = count;
|
*_probes = count;
|
||||||
*_min = min;
|
*_min = min;
|
||||||
*_max = max;
|
*_max = max;
|
||||||
*_avg = avg / (double)count;
|
*_avg = avg;
|
||||||
|
|
||||||
if (_time) {
|
if (_time) {
|
||||||
// if (fsk->cnetz->dsp_mode == DSP_MODE_SPK_V)
|
// 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;
|
*_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)
|
static inline void got_bit(fsk_fm_demod_t *fsk, int bit, double change_level)
|
||||||
|
@ -348,11 +360,11 @@ got_sync:
|
||||||
if (debug)
|
if (debug)
|
||||||
fprintf(fsk->debug_fp, " SYNC!");
|
fprintf(fsk->debug_fp, " SYNC!");
|
||||||
#endif
|
#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;
|
fsk->sync_level = avg;
|
||||||
if (fsk->sync == FSK_SYNC_NEGATIVE)
|
if (fsk->sync == FSK_SYNC_NEGATIVE)
|
||||||
fsk->sync_level = -fsk->sync_level;
|
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->level_threshold = (double)avg;
|
||||||
fsk->rx_sync = 0;
|
fsk->rx_sync = 0;
|
||||||
fsk->rx_buffer_count = 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)) */
|
/* 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);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -457,7 +470,7 @@ static inline void find_change_slope(fsk_fm_demod_t *fsk)
|
||||||
fsk->last_change_positive = change_positive;
|
fsk->last_change_positive = change_positive;
|
||||||
if (!fsk->sync) {
|
if (!fsk->sync) {
|
||||||
fsk->next_bit = 1.5;
|
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) {
|
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;
|
fsk->last_change_positive = change_positive;
|
||||||
if (!fsk->sync) {
|
if (!fsk->sync) {
|
||||||
fsk->next_bit = 1.5;
|
fsk->next_bit = 1.5;
|
||||||
/* if bit change is inside window, we can get level from end of window */
|
/* if bit change is inside window, we can get level from borders of window */
|
||||||
s = fsk->bit_buffer_spl[(fsk->bit_buffer_pos + fsk->bit_buffer_len - 1) % fsk->bit_buffer_len];
|
s = fsk->bit_buffer_spl[fsk->bit_buffer_pos];
|
||||||
got_bit(fsk, change_positive, fabs(s));
|
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) {
|
if (fsk->next_bit <= 0.0) {
|
||||||
|
|
|
@ -39,7 +39,7 @@ typedef struct fsk_fm_demod {
|
||||||
enum fsk_sync sync; /* set, if we are in sync and what polarity we receive */
|
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_level; /* what was the level, when we received the sync */
|
||||||
double sync_time; /* when did we receive sync, relative to super frame */
|
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 */
|
/* speech */
|
||||||
sample_t *speech_buffer; /* holds one chunk of 12.5ms */
|
sample_t *speech_buffer; /* holds one chunk of 12.5ms */
|
||||||
|
|
|
@ -1462,7 +1462,7 @@ static const char *deinterleave(const char *input)
|
||||||
return output;
|
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;
|
telegramm_t telegramm;
|
||||||
uint8_t opcode;
|
uint8_t opcode;
|
||||||
|
@ -1489,12 +1489,11 @@ void cnetz_decode_telegramm(cnetz_t *cnetz, const char *bits, double level, doub
|
||||||
opcode = telegramm.opcode;
|
opcode = telegramm.opcode;
|
||||||
telegramm.level = level;
|
telegramm.level = level;
|
||||||
telegramm.sync_time = sync_time;
|
telegramm.sync_time = sync_time;
|
||||||
telegramm.jitter = jitter;
|
|
||||||
|
|
||||||
if (bit_errors)
|
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
|
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) {
|
if (cnetz->sender.loopback) {
|
||||||
PDEBUG(DFRAME, DEBUG_NOTICE, "Received Telegramm in loopback test mode (opcode %d = %s)\n", opcode, definition_opcode[opcode].message_name);
|
PDEBUG(DFRAME, DEBUG_NOTICE, "Received Telegramm in loopback test mode (opcode %d = %s)\n", opcode, definition_opcode[opcode].message_name);
|
||||||
|
|
|
@ -61,7 +61,6 @@
|
||||||
typedef struct telegramm {
|
typedef struct telegramm {
|
||||||
double level; /* average level of received sync sequence */
|
double level; /* average level of received sync sequence */
|
||||||
double sync_time; /* when did we receive the sync for this frame */
|
double sync_time; /* when did we receive the sync for this frame */
|
||||||
double jitter; /* phase jitter of sync sequence */
|
|
||||||
uint8_t opcode;
|
uint8_t opcode;
|
||||||
/* used parameters depend on opcode */
|
/* used parameters depend on opcode */
|
||||||
uint8_t fuz_fuvst_nr;
|
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 match_futln(telegramm_t *telegramm, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest);
|
||||||
|
|
||||||
int detect_sync(uint64_t bitstream);
|
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);
|
const char *cnetz_encode_telegramm(cnetz_t *cnetz);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue