moved ddc to own files

master
Ahmet Inan 2011-09-08 13:56:45 +02:00
rodzic 04e68c262f
commit 07236f86cd
4 zmienionych plików z 104 dodań i 86 usunięć

Wyświetl plik

@ -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

77
ddc.c 100644
Wyświetl plik

@ -0,0 +1,77 @@
#include <math.h>
#include <stdlib.h>
#include <complex.h>
#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);
}

25
ddc.h 100644
Wyświetl plik

@ -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

Wyświetl plik

@ -8,7 +8,7 @@
#include <time.h>
#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;