From 89fa345e9ee4778b5f0391b5ab1cfc043aadc1d9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 22 Apr 2004 22:20:13 +0000 Subject: COmmit missing stuff git-svn-id: file:///home/lennart/svn/public/vfax/trunk@4 541b366f-4dd8-0310-ae39-b2612fd50714 --- Makefile | 2 +- qbuf.c | 62 +++++++++++++++++++++++++++++++ qbuf.h | 22 +++++++++++ qbufsplit.c | 33 +++++++++++++++++ qbufsplit.h | 10 +++++ resample.c | 90 ++++++++++++++++++++++---------------------- resample.h | 14 ++++++- v17dem.c | 121 ++++++++++++++++++++++++++---------------------------------- v17tcm.h | 2 + 9 files changed, 240 insertions(+), 116 deletions(-) create mode 100644 qbuf.c create mode 100644 qbuf.h create mode 100644 qbufsplit.c create mode 100644 qbufsplit.h diff --git a/Makefile b/Makefile index 45cc029..a697177 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ all: main *.o: Makefile -main: main.o v17tcm.o v17mod.o bitsplit.o util.o interpol.o resample.o +main: main.o v17tcm.o v17mod.o bitsplit.o util.o interpol.o resample.o qbuf.o qbufsplit.o $(CC) -o $@ $^ $(LIBS) clean: diff --git a/qbuf.c b/qbuf.c new file mode 100644 index 0000000..d225ce7 --- /dev/null +++ b/qbuf.c @@ -0,0 +1,62 @@ +#include +#include +#include + +#include "qbuf.h" + +void qbuf_init(struct qbuf *q, size_t length) { + assert(q && length); + memset(q, 0, sizeof(struct qbuf)); + + q->data = malloc(q->length = length*2); + assert(q->data); +} + +void qbuf_done(struct qbuf *q) { + assert(q); + free(q->data); +} + +static void move_to_front(struct qbuf *q) { + assert(q); + + if (q->index+q->fill <= q->length/2) + return; + + memmove(q->data, q->data+q->index, q->fill); + q->index = 0; +} + +void* qbuf_push(struct qbuf *q, size_t *l) { + size_t m; + assert(q); + + move_to_front(q); + m = q->length - q->fill - q->index; + *l = m; + return q->data + q->index + q->fill; +} + +void qbuf_push_validate(struct qbuf *q, size_t l) { + assert(q); + q->fill += l; + assert(q->index+q->fill <= q->length); +} + +void* qbuf_pull(struct qbuf *q, size_t *l) { + assert(q); + *l = q->fill; + return q->data + q->index; +} + +void qbuf_pull_invalidate(struct qbuf *q, size_t l) { + assert(q); + + assert(l <= q->fill); + q->fill -= l; + q->index += l; + + assert(q->index+q->fill <= q->length); + if (!q->fill) + q->index = 0; +} diff --git a/qbuf.h b/qbuf.h new file mode 100644 index 0000000..12d07b7 --- /dev/null +++ b/qbuf.h @@ -0,0 +1,22 @@ +#ifndef fooqbufhfoo +#define fooqbufhfoo + +/* $Id$ */ + +#include + +struct qbuf { + void *data; + size_t length, index, fill; +}; + +void qbuf_init(struct qbuf *q, size_t length); +void qbuf_done(struct qbuf *q); + +void* qbuf_push(struct qbuf *q, size_t *l); +void qbuf_push_validate(struct qbuf *q, size_t l); + +void* qbuf_pull(struct qbuf *q, size_t *l); +void qbuf_pull_invalidate(struct qbuf *q, size_t l); + +#endif diff --git a/qbufsplit.c b/qbufsplit.c new file mode 100644 index 0000000..e03d1a3 --- /dev/null +++ b/qbufsplit.c @@ -0,0 +1,33 @@ +#include + +#include "qbufsplit.h" + +void qbuf_float_split(struct qbuf* sq, struct qbuf* dq1, struct qbuf*dq2) { + float *sp, *dp1, *dp2; + size_t sl, dl1, dl2; + size_t c = 0; + + assert(sq && dq1 && dq2); + + sp = qbuf_pull(sq, &sl); + dp1 = qbuf_push(dq1, &dl1); + dp2 = qbuf_push(dq2, &dl2); + + assert(sp && dp1 && dp2); + + while (sl >= 2*sizeof(float) && dl1 >= sizeof(float) && dl2 >= sizeof(float)) { + + *(dp1++) = *(sp++); + *(dp2++) = *(sp++); + + sl -= 2*sizeof(float); + dl1 -= sizeof(float); + dl2 -= sizeof(float); + + c += sizeof(float); + } + + qbuf_pull_invalidate(sq, c*2); + qbuf_push_validate(dq1, c); + qbuf_push_validate(dq2, c); +} diff --git a/qbufsplit.h b/qbufsplit.h new file mode 100644 index 0000000..05762b4 --- /dev/null +++ b/qbufsplit.h @@ -0,0 +1,10 @@ +#ifndef fooqbufsplithfoo +#define fooqbufsplithfoo + +/* $Id$ */ + +#include "qbuf.h" + +void qbuf_float_split(struct qbuf* sq, struct qbuf* dq1, struct qbuf*dq2); + +#endif diff --git a/resample.c b/resample.c index ee9e540..3ed5c05 100644 --- a/resample.c +++ b/resample.c @@ -9,14 +9,6 @@ #define SINC_RADIUS 10 -struct resample_state { - float delta; - - int sfreq, dfreq; - struct interpol_state interpol; -}; - - static int lcd(int a, int b) { assert(a >= 1 && b >= 1); @@ -44,13 +36,13 @@ void resample_done(struct resample_state *s) { interpol_done(&s->interpol); } -void resample_get(struct resample_state *s, float* sp, int *sl, float *dp, int *dl, int sfreq, int dfreq) { +void resample_get(struct resample_state *s, struct qbuf *sq, struct qbuf *dq, int sfreq, int dfreq) { int di; float x = 0; - - assert(s && sp && dp && sfreq > 0 && dfreq > 0); - assert(*sl > 0); - assert(*dl > 0); + float *sp, *dp; + size_t sl, dl; + + assert(s && sq && dq && sfreq > 0 && dfreq > 0); if (sfreq != s->sfreq || dfreq != s->dfreq) { interpol_done(&s->interpol); @@ -59,38 +51,50 @@ void resample_get(struct resample_state *s, float* sp, int *sl, float *dp, int * s->dfreq = dfreq; } + sp = qbuf_pull(sq, &sl); + dp = qbuf_push(dq, &dl); + + assert(sp && dp && sl && dl); + + sl /= sizeof(float); + dl /= sizeof(float); + di = 0; - while (di < *dl) { + while (di < dl) { x = (float) di*sfreq/dfreq + s->delta; - if (x + SINC_RADIUS + 1 > *sl) + if (x + SINC_RADIUS + 1 > sl) break; - *(dp++) = interpol_get(&s->interpol, sp, *sl, x); + *(dp++) = interpol_get(&s->interpol, sp, sl, x); di++; } - *dl = di; + qbuf_push_validate(dq, di*sizeof(float)); if (x >= SINC_RADIUS) { - *sl = (int) (x - SINC_RADIUS); - s->delta = x - *sl; - } else - *sl = 0; + int rn; + rn = (int) (x - SINC_RADIUS); + assert(rn <= sl); + s->delta = x - rn; + fprintf(stderr, "foo\n"); + qbuf_pull_invalidate(sq, rn*sizeof(float)); + fprintf(stderr, "bar\n"); + } } #if (TEST == 7) #define BUFSIZE (10*1024) -void sinbuf(float *buf, int l) { +static void sinbuf(float *buf, int l) { static int i = 0; for (; l > 0; l--, i = (i+1 == 100) ? 0 : i+1) *(buf++) = sin(i*2*M_PI/100); } -void convbuf(float *buf, int l) { +static void convbuf(float *buf, int l) { int16_t *p = (int16_t*) buf; for (; l > 0; l--, p+=2) { float v = ((float) *p + (float) *(p+1))/0x7FFF; @@ -102,44 +106,40 @@ void convbuf(float *buf, int l) { int main(int argc, char *argv[]) { struct resample_state resample; - float inbuf[BUFSIZE]; - int total_n_inbuf = 0; - + struct qbuf qi, qo; + if (argc > 1) { stdin = fopen(argv[1], "r"); assert(stdin); } + qbuf_init(&qi, BUFSIZE); + qbuf_init(&qo, BUFSIZE); resample_init(&resample); while (!feof(stdin)) { - float outbuf[BUFSIZE]; - int n_outbuf = sizeof(outbuf) / sizeof(float); - int n_inbuf, c; - + int c; + float *ip, *up; + size_t il, ol; + fprintf(stderr, "LOOP!\n"); - c = fread(inbuf + total_n_inbuf, sizeof(float), sizeof(inbuf)/sizeof(float) - total_n_inbuf, stdin); - convbuf(inbuf + total_n_inbuf, c); - n_inbuf = (total_n_inbuf += c); - + ip = qbuf_push(&qi, &il); - -/* sinbuf(inbuf + total_n_inbuf, sizeof(inbuf)/sizeof(float) - total_n_inbuf); */ -/* n_inbuf = total_n_inbuf = sizeof(inbuf)/sizeof(float); *\/ */ - + c = fread(ip, sizeof(float), il/sizeof(float), stdin); + convbuf(ip, c); + qbuf_push_validate(&qi, c*sizeof(float)); - resample_get(&resample, inbuf, &n_inbuf, outbuf, &n_outbuf, 44100, 8000); - - fwrite(outbuf, sizeof(float), n_outbuf, stdout); + resample_get(&resample, &qi, &qo, 44100, 8000); - if (n_inbuf) { - total_n_inbuf -= n_inbuf; - memmove(inbuf, inbuf + n_inbuf, total_n_inbuf*sizeof(float)); - } + up = qbuf_pull(&qo, &ol); + fwrite(up, sizeof(float), ol/sizeof(float), stdout); + qbuf_pull_invalidate(&qo, ol); } resample_done(&resample); + qbuf_done(&qi); + qbuf_done(&qo); return 0; } diff --git a/resample.h b/resample.h index a2905b3..e1ce8e6 100644 --- a/resample.h +++ b/resample.h @@ -1,11 +1,21 @@ #ifndef fooresamplehfoo #define fooresamplehfoo -struct resample_state; +/* $Id$ */ + +#include "interpol.h" +#include "qbuf.h" + +struct resample_state { + float delta; + + int sfreq, dfreq; + struct interpol_state interpol; +}; void resample_init(struct resample_state *s); void resample_done(struct resample_state *s); -void resample_get(struct resample_state *s, float* sp, int *sl, float *dp, int *dl, int sfreq, int dfreq); +void resample_get(struct resample_state *s, struct qbuf *sq, struct qbuf *dq, int sfreq, int dfreq); #endif diff --git a/v17dem.c b/v17dem.c index 4fad8f3..5f2e832 100644 --- a/v17dem.c +++ b/v17dem.c @@ -5,98 +5,83 @@ #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; + + struct resample_state qam_resample, xam_resample, yam_resample; + struct qbuf am_qbuf, xam_qbuf, yam_qbuf, xsymbols_qbuf, ysymbols_qbuf; }; -void v17dem_init(struct v17dem_state *s) { - assert(s); +static int v17_7k2_symbol_decode(float x, float y) { + int row, col, i; - 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); + static const int v17_7k2_table[] = { + 3, 10, 5, 0, + 6, 15, 12, 9, + 13, 8, 11, 2, + 4, 1, 14, 7 + }; - interpol_init(&s->qam_interpol, 9, SINC_RADIUS); -} + col = (int) ((x+.6)/.4 +.5); + if (col < 0) col = 0; + if (col > 3) col = 3; -void v17dem_done(struct v17dem_state *s) { - assert(s); + row = (int) ((y+.6)/.4 +.5); + if (row < 0) row = 0; + if (row > 3) row = 3; - free(s->samples); - inertpol_done(&s->qam_interpol); -} - -static void move_to_front(struct v17dem_state *s) { - assert(s); + i = col*4+row; - if (s->i_samples < SAMPLES_MAX) - return; + assert(i >= 0 && i <= 15); - memmove(s->samples, s->samples + s->i_samples, s->n_samples*sizeof(float)); - s->i_samples = 0; + return v17_7k2_table[i]; } -void v17dem_push(struct v17dem_state *s, const float *p, int l){ - assert(s && p && l); +void v17dem_init(struct v17dem_state *s) { + assert(s); - assert(l <= SAMPLES_MAX-s->n_samples); + memset(s, 0, sizeof(struct v17dem_state)); + s->baud_rate = INITIAL_BAUD_RATE; + s->carrier_freq = INITIAL_CARRIER_FREQ; - move_to_front(s); + resample_init(&s->qam_resample); + resample_init(&s->xam_resample); + resample_init(&s->yam_resample); - memcpy(s->samples + s->i_samples + s->n_samples, p, l*sizeof(float)); - s->n_samples += l; + qbuf_init(&s->am_qbuf, sizeof(float) * SAMPLES_MAX); + qbuf_init(&s->xam_qbuf, sizeof(float) * SAMPLES_MAX/2); + qbuf_init(&s->yam_qbuf, sizeof(float) * SAMPLES_MAX/2); + qbuf_init(&s->xsymbols_qbuf, sizeof(float) * SAMPLES_MAX/2); + qbuf_init(&s->ysymbols_qbuf, sizeof(float) * SAMPLES_MAX/2); } -int v17dem_pull(struct v17dem_state *s, uint8_t *p, int l){ - int alt = 0; - - assert(s && p && l); +void v17dem_done(struct v17dem_state *s) { + assert(s); - 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); + resample_done(&s->qam_resample); + resample_done(&s->xam_resample); + resample_done(&s->yam_resample); - /* AM-Abtatsung druchführen */ - if (s->current = COSINUS) - am = s->xam; - else - am = s->yam; + qbuf_done(&s->am_qbuf); + qbuf_done(&s->xam_qbuf); + qbuf_done(&s->yam_qbuf); + qbuf_done(&s->xsymbols_qbuf); + qbuf_done(&s->ysymbols_qbuf); +} - am[s->am_index] = interpol_get(s->qam_interpol, s->samples + s->i_samples, s->n_samples, x); +static int v17_decode(struct qbuf - if (s->current == SINUS) - s->am_index++; - - s->current = !s->current; - /* Überflüssige Sampledaten killen */ +int v17dem_run(struct v17dem_state *s, struct qbuf *sample_qbuf, struct qbuf *byte_qbuf){ + assert(s && sample_qbuf && byte_qbuf); - n = (int) (x - (float) SINC_RADIUS*SAMPLE_RATE/s->carrier_freq/4); + resample_get(s->qam_resample, sample_qbuf, s->am_qbuf, SAMPLE_RATE, s->carrier_freq*4); + qbuf_float_split(s->am_qbuf, s->xam_qbuf, s->yam_qbuf); + resample_get(s->xam_resample, s->xam_qbuf, s->xsymbols_qbuf); + resample_get(s->yam_resample, s->yam_qbuf, s->ysymbols_qbuf); - if (n > 0) { - s->n_samples -= n; - s->i_samples += n; - s->sample_index += n; - } - } + v17_decode(s->xsymbols_qbuf, s->ysymbols_qbuf, byte_qbuf), + } diff --git a/v17tcm.h b/v17tcm.h index f126714..790c31f 100644 --- a/v17tcm.h +++ b/v17tcm.h @@ -1,6 +1,8 @@ #ifndef foov17tcmhfoo #define foov17tcmhfoo +/* $Id$ */ + #include struct v17tcm_state { -- cgit