74 lines
2.8 KiB
C
74 lines
2.8 KiB
C
|
|
#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_AUTO, /* auto selection of the demod type below */
|
|
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_stddev; /* standard deviation of level changes */
|
|
|
|
/* 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 */
|
|
|
|
/* display measurements */
|
|
dispmeasparam_t *dmp_frame_level;
|
|
dispmeasparam_t *dmp_frame_stddev;
|
|
|
|
/* 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);
|
|
|