diff options
author | Lennart Poettering <lennart@poettering.net> | 2004-04-18 01:35:53 +0000 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2004-04-18 01:35:53 +0000 |
commit | 783b56d54788f177881d68ae2ec7a7cb4bb38ac4 (patch) | |
tree | 77555207fa13c137e0c8dab8726f2ed96538e075 /v17dem.c | |
parent | f069d236c79a7cb89542eba5ddc454d03ead5394 (diff) |
Initial commit
git-svn-id: file:///home/lennart/svn/public/vfax/trunk@3 541b366f-4dd8-0310-ae39-b2612fd50714
Diffstat (limited to 'v17dem.c')
-rw-r--r-- | v17dem.c | 102 |
1 files changed, 102 insertions, 0 deletions
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; + } + } +} |