From 783b56d54788f177881d68ae2ec7a7cb4bb38ac4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 18 Apr 2004 01:35:53 +0000 Subject: Initial commit git-svn-id: file:///home/lennart/svn/public/vfax/trunk@3 541b366f-4dd8-0310-ae39-b2612fd50714 --- v17dem.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 v17dem.c (limited to 'v17dem.c') diff --git a/v17dem.c b/v17dem.c new file mode 100644 index 0000000..4fad8f3 --- /dev/null +++ b/v17dem.c @@ -0,0 +1,102 @@ +#include "v17dem.h" + +#define INITIAL_BAUD_RATE 2400 +#define INITIAL_CARRIER_FREQ 1800 +#define SAMPLE_RATE 8000 +#define SAMPLES_MAX (SAMPLES_RATE*5) /* -> 5s buffer */ + +#define SINC_RADIUS 10 + +struct v17dem_state { + float *samples; + int i_samples, n_samples; + + int sample_index; + + int baud_rate; + int carrier_freq; + + struct interpol_state qam_interpol; + struct interpol_state am_interpol; + + enum { COSINUS, SINUS } current; + float *xam, *yam; + int am_index; +}; + + +void v17dem_init(struct v17dem_state *s) { + assert(s); + + memset(s, 0, sizeof(struct v17dem_state)); + s->baud_rate = INITIAL_BAUD_RATE; + s->carrier_freq = INITIAL_CARRIER_FREQ; + s->samples = malloc(sizeof(float) * SAMPLES_MAX * 2); + + interpol_init(&s->qam_interpol, 9, SINC_RADIUS); +} + +void v17dem_done(struct v17dem_state *s) { + assert(s); + + free(s->samples); + inertpol_done(&s->qam_interpol); +} + +static void move_to_front(struct v17dem_state *s) { + assert(s); + + if (s->i_samples < SAMPLES_MAX) + return; + + memmove(s->samples, s->samples + s->i_samples, s->n_samples*sizeof(float)); + s->i_samples = 0; +} + +void v17dem_push(struct v17dem_state *s, const float *p, int l){ + assert(s && p && l); + + assert(l <= SAMPLES_MAX-s->n_samples); + + move_to_front(s); + + memcpy(s->samples + s->i_samples + s->n_samples, p, l*sizeof(float)); + s->n_samples += l; +} + +int v17dem_pull(struct v17dem_state *s, uint8_t *p, int l){ + int alt = 0; + + assert(s && p && l); + + for (;;) { + int n; + + /* Position für AM-Abtastung im Sample-Puffer berechnen -- alle 90° */ + float x = (SAMPLE_RATE/(4.0*s->carrier_freq) * s->am_index) - s->sample_index; + assert(x >= 0); + + /* AM-Abtatsung druchführen */ + if (s->current = COSINUS) + am = s->xam; + else + am = s->yam; + + am[s->am_index] = interpol_get(s->qam_interpol, s->samples + s->i_samples, s->n_samples, x); + + if (s->current == SINUS) + s->am_index++; + + s->current = !s->current; + + /* Überflüssige Sampledaten killen */ + + n = (int) (x - (float) SINC_RADIUS*SAMPLE_RATE/s->carrier_freq/4); + + if (n > 0) { + s->n_samples -= n; + s->i_samples += n; + s->sample_index += n; + } + } +} -- cgit