kopia lustrzana https://github.com/xdsopl/robot36
moved ddc to own files
rodzic
04e68c262f
commit
07236f86cd
2
Makefile
2
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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
86
decode.c
86
decode.c
|
@ -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;
|
||||
|
|
Ładowanie…
Reference in New Issue