C-Netz: SDR now uses zero-crossing to detect level changes.
This does not work with analog radio, but with SDR it works. The quality should be better and the process is faster.
This commit is contained in:
68
src/cnetz/fsk_demod.h
Normal file
68
src/cnetz/fsk_demod.h
Normal file
@@ -0,0 +1,68 @@
|
||||
|
||||
#define BITS_PER_SUPERFRAME 12672.0 /* super frame (Oberrahmen) has duration of excactly 2.4 seconds */
|
||||
#define BITS_PER_BLOCK 198.0 /* block has duration of excactly 37.5 milli seconds */
|
||||
#define BITS_PER_SPK_BLOCK 66.0 /* spk block has a duration of exactly 12.5 milli seconds */
|
||||
|
||||
/* fsk rx sync state */
|
||||
enum fsk_sync {
|
||||
FSK_SYNC_NONE = 0,
|
||||
FSK_SYNC_POSITIVE,
|
||||
FSK_SYNC_NEGATIVE,
|
||||
};
|
||||
|
||||
enum demod_type {
|
||||
FSK_DEMOD_SLOPE, /* check for highest slope (good for sound cards) */
|
||||
FSK_DEMOD_LEVEL, /* check for zero crossing (good for SDR) */
|
||||
};
|
||||
|
||||
typedef struct cnetz cnetz_t;
|
||||
|
||||
typedef struct fsk_fm_demod {
|
||||
cnetz_t *cnetz; /* pointer back to cnetz instance */
|
||||
|
||||
/* clock */
|
||||
double bit_time; /* current time in bits inside superframe */
|
||||
double bit_time_uncorrected; /* same as above, but not corrected by sync */
|
||||
|
||||
/* bit detection */
|
||||
enum demod_type demod_type; /* how to demodulate bits */
|
||||
sample_t *bit_buffer_spl; /* samples ring buffer */
|
||||
int bit_buffer_len; /* number of samples in ring buffer */
|
||||
int bit_buffer_half; /* half of ring buffer */
|
||||
int bit_buffer_pos; /* current position to write next sample */
|
||||
double level_threshold; /* threshold for detection of next level change */
|
||||
double bits_per_sample; /* duration of one sample in bits */
|
||||
double next_bit; /* count time to detect bits */
|
||||
int bit_count; /* counts bits, to match 4 bits at distributed signaling */
|
||||
int last_change_positive; /* flags last level change direction */
|
||||
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 */
|
||||
|
||||
/* speech */
|
||||
sample_t *speech_buffer; /* holds one chunk of 12.5ms */
|
||||
int speech_size;
|
||||
int speech_count;
|
||||
|
||||
/* bit decoder */
|
||||
uint64_t rx_sync; /* sync shift register */
|
||||
char rx_buffer[151]; /* 150 bits + termination */
|
||||
int rx_buffer_count; /* counter when receiving bits */
|
||||
|
||||
/* statistics */
|
||||
double change_levels[256]; /* ring buffer to store levels */
|
||||
double change_when[256]; /* ring buffer to store time when level has changed */
|
||||
uint8_t change_pos; /* index for next write */
|
||||
|
||||
/* debug */
|
||||
FILE *debug_fp; /* file pointer for debugging output */
|
||||
} fsk_fm_demod_t;
|
||||
|
||||
int fsk_fm_init(fsk_fm_demod_t *fsk, cnetz_t *cnetz, int samplerate, double bitrate, enum demod_type);
|
||||
void fsk_fm_exit(fsk_fm_demod_t *fsk);
|
||||
void fsk_fm_demod(fsk_fm_demod_t *fsk, sample_t *samples, int length);
|
||||
void fsk_correct_sync(fsk_fm_demod_t *fsk, double offset);
|
||||
void fsk_copy_sync(fsk_fm_demod_t *fsk_to, fsk_fm_demod_t *fsk_from);
|
||||
void fsk_demod_reset(fsk_fm_demod_t *fsk);
|
||||
|
Reference in New Issue
Block a user