From 07236f86cdb27be41f7481884a81cdd135c6c4f4 Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Thu, 8 Sep 2011 13:56:45 +0200 Subject: [PATCH] moved ddc to own files --- Makefile | 2 +- ddc.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ ddc.h | 25 ++++++++++++++++ decode.c | 86 +------------------------------------------------------- 4 files changed, 104 insertions(+), 86 deletions(-) create mode 100644 ddc.c create mode 100644 ddc.h diff --git a/Makefile b/Makefile index 105447f..c31ebb5 100644 --- a/Makefile +++ b/Makefile @@ -22,5 +22,5 @@ clean: encode: encode.o mmap_file.o -decode: decode.o mmap_file.o pcm.o wav.o alsa.o window.o +decode: decode.o mmap_file.o pcm.o wav.o alsa.o window.o ddc.o diff --git a/ddc.c b/ddc.c new file mode 100644 index 0000000..92a8ec4 --- /dev/null +++ b/ddc.c @@ -0,0 +1,77 @@ + +#include +#include +#include +#include "window.h" +#include "ddc.h" + +void do_ddc(ddc_t *ddc, float *input, float complex *output) +{ + int in = 0; + ddc->s[ddc->last] = input[in++]; + ddc->last = (ddc->last + 1) < ddc->samples ? ddc->last + 1 : 0; + ddc->skip += ddc->L; + // this works only for L <= M + for (int k = 0; k < ddc->L; k++) { + float complex sum = 0.0; + for (int i = ddc->offset, j = ddc->last; i < ddc->taps; i += ddc->L) { + sum += ddc->b[i] * ddc->s[j]; + j += j ? - 1 : ddc->samples - 1; + } + + ddc->offset = (ddc->offset + ddc->M) % ddc->L; + + while (ddc->skip < ddc->M) { + ddc->s[ddc->last] = input[in++]; + ddc->last = (ddc->last + 1) < ddc->samples ? ddc->last + 1 : 0; + ddc->skip += ddc->L; + } + + ddc->skip %= ddc->M; + output[k] = ddc->osc * sum; + ddc->osc *= ddc->d; +// ddc->osc /= cabsf(ddc->osc); // not really needed + } +} +ddc_t *alloc_ddc(float freq, float bw, float step, int taps, int L, int M, float (*window)(float, float)) +{ + float lstep = step / (float)L; + float ostep = step * (float)M / (float)L; + ddc_t *ddc = malloc(sizeof(ddc_t)); + ddc->taps = taps; + ddc->samples = (taps + L - 1) / L; + ddc->b = malloc(sizeof(float complex) * ddc->taps); + ddc->s = malloc(sizeof(float) * ddc->samples); + ddc->osc = I; + ddc->d = cexpf(-I * 2.0 * M_PI * freq * ostep); + ddc->offset = 0; + ddc->last = 0; + ddc->skip = 0; + ddc->L = L; + ddc->M = M; + for (int i = 0; i < ddc->samples; i++) + ddc->s[i] = 0.0; + float sum = 0.0; + for (int i = 0; i < ddc->taps; i++) { + float N = (float)ddc->taps; + float n = (float)i; + float x = n - (N - 1.0) / 2.0; + float l = 2.0 * M_PI * bw * lstep; + float w = window(n, ddc->taps); + float h = 0.0 == x ? l / M_PI : sinf(l * x) / (x * M_PI); + float b = w * h; + sum += b; + complex float o = cexpf(I * 2.0 * M_PI * freq * lstep * n); + ddc->b[i] = b * o * (float)L; + } + for (int i = 0; i < ddc->taps; i++) + ddc->b[i] /= sum; + return ddc; +} +void free_ddc(ddc_t *ddc) +{ + free(ddc->b); + free(ddc->s); + free(ddc); +} + diff --git a/ddc.h b/ddc.h new file mode 100644 index 0000000..d7e2ba9 --- /dev/null +++ b/ddc.h @@ -0,0 +1,25 @@ + +#ifndef DDC_H +#define DDC_H +#include "window.h" + +typedef struct { + float complex *b; + float *s; + float complex osc; + float complex d; + int offset; + int skip; + int last; + int taps; + int samples; + int L; + int M; +} ddc_t; + +void do_ddc(ddc_t *, float *, float complex *); +ddc_t *alloc_ddc(float, float, float, int, int, int, float (*)(float, float)); +void free_ddc(ddc_t *); + +#endif + diff --git a/decode.c b/decode.c index 0c8d39e..01d2a86 100644 --- a/decode.c +++ b/decode.c @@ -8,7 +8,7 @@ #include #include "mmap_file.h" #include "pcm.h" -#include "window.h" +#include "ddc.h" float lerp(float a, float b, float x) { @@ -31,90 +31,6 @@ float limit(float min, float max, float x) return tmp > max ? max : tmp; } -typedef struct { - float complex *b; - float *s; - float complex osc; - float complex d; - int offset; - int skip; - int last; - int taps; - int samples; - int L; - int M; -} ddc_t; - -void do_ddc(ddc_t *ddc, float *input, float complex *output) -{ - int in = 0; - ddc->s[ddc->last] = input[in++]; - ddc->last = (ddc->last + 1) < ddc->samples ? ddc->last + 1 : 0; - ddc->skip += ddc->L; - // this works only for L <= M - for (int k = 0; k < ddc->L; k++) { - float complex sum = 0.0; - for (int i = ddc->offset, j = ddc->last; i < ddc->taps; i += ddc->L) { - sum += ddc->b[i] * ddc->s[j]; - j += j ? - 1 : ddc->samples - 1; - } - - ddc->offset = (ddc->offset + ddc->M) % ddc->L; - - while (ddc->skip < ddc->M) { - ddc->s[ddc->last] = input[in++]; - ddc->last = (ddc->last + 1) < ddc->samples ? ddc->last + 1 : 0; - ddc->skip += ddc->L; - } - - ddc->skip %= ddc->M; - output[k] = ddc->osc * sum; - ddc->osc *= ddc->d; -// ddc->osc /= cabsf(ddc->osc); // not really needed - } -} -ddc_t *alloc_ddc(float freq, float bw, float step, int taps, int L, int M, float (*window)(float, float)) -{ - float lstep = step / (float)L; - float ostep = step * (float)M / (float)L; - ddc_t *ddc = malloc(sizeof(ddc_t)); - ddc->taps = taps; - ddc->samples = (taps + L - 1) / L; - ddc->b = malloc(sizeof(float complex) * ddc->taps); - ddc->s = malloc(sizeof(float) * ddc->samples); - ddc->osc = I; - ddc->d = cexpf(-I * 2.0 * M_PI * freq * ostep); - ddc->offset = 0; - ddc->last = 0; - ddc->skip = 0; - ddc->L = L; - ddc->M = M; - for (int i = 0; i < ddc->samples; i++) - ddc->s[i] = 0.0; - float sum = 0.0; - for (int i = 0; i < ddc->taps; i++) { - float N = (float)ddc->taps; - float n = (float)i; - float x = n - (N - 1.0) / 2.0; - float l = 2.0 * M_PI * bw * lstep; - float w = window(n, ddc->taps); - float h = 0.0 == x ? l / M_PI : sinf(l * x) / (x * M_PI); - float b = w * h; - sum += b; - complex float o = cexpf(I * 2.0 * M_PI * freq * lstep * n); - ddc->b[i] = b * o * (float)L; - } - for (int i = 0; i < ddc->taps; i++) - ddc->b[i] /= sum; - return ddc; -} -void free_ddc(ddc_t *ddc) -{ - free(ddc->b); - free(ddc->s); - free(ddc); -} - typedef struct { float *s; int last;