WIP
This commit is contained in:
parent
679b37dc35
commit
d42f63388e
|
@ -8,6 +8,10 @@
|
|||
#include "fir.h"
|
||||
|
||||
/* Below are all the includes used throughout the library. */
|
||||
#include <alloca.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* options for text editors
|
||||
vim: expandtab:ts=4:sw=4
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
/* libfir/src/libfir/100_fir.c
|
||||
*
|
||||
* Copyright: ©2014, Laurence Withers.
|
||||
* Author: Laurence Withers <l@lwithers.me.uk>
|
||||
* License: GPLv3
|
||||
*/
|
||||
|
||||
|
||||
|
||||
struct fir_symm_store {
|
||||
double* d;
|
||||
int pos, size;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct fir_filter_t {
|
||||
double* coeff;
|
||||
int ncoeff;
|
||||
|
||||
int primed;
|
||||
double* x;
|
||||
int xpos;
|
||||
|
||||
enum fir_symmetry symm;
|
||||
int nsymm;
|
||||
struct fir_symm_store* symm_store;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void
|
||||
symm_setup(struct fir_filter_t* fi, int delay)
|
||||
{
|
||||
int i;
|
||||
|
||||
fi->symm_store = malloc(sizeof(struct fir_symm_store) * fi->nsymm);
|
||||
for(i = 0; i < fi->nsymm; ++i) {
|
||||
fi->symm_store[i].d = malloc(sizeof(double) * delay);
|
||||
fi->symm_store[i].pos = 0;
|
||||
fi->symm_store[i].size = delay;
|
||||
delay -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct fir_filter_t*
|
||||
fir_filter_new(const double* coeff, int ncoeff, enum fir_symmetry symm)
|
||||
{
|
||||
struct fir_filter_t* fi = malloc(sizeof(*fi));
|
||||
|
||||
fi->coeff = malloc(sizeof(double) * ncoeff);
|
||||
memcpy(fi->coeff, coeff, sizeof(double) * ncoeff);
|
||||
fi->ncoeff = ncoeff;
|
||||
|
||||
fi->primed = 0;
|
||||
fi->x = malloc(sizeof(double) * ncoeff);
|
||||
fi->xpos = 0;
|
||||
|
||||
fi->symm = symm;
|
||||
switch(symm) {
|
||||
case fir_symmetry_none:
|
||||
fi->nsymm = 0;
|
||||
fi->symm_store = 0;
|
||||
break;
|
||||
|
||||
case fir_symmetry_odd:
|
||||
fi->nsymm = ncoeff - 1;
|
||||
symm_setup(fi, 2 * ncoeff - 1);
|
||||
break;
|
||||
|
||||
case fir_symmetry_even:
|
||||
fi->nsymm = ncoeff;
|
||||
symm_setup(fi, 2 * ncoeff);
|
||||
break;
|
||||
}
|
||||
|
||||
return fi;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
fir_filter_free(struct fir_filter_t* fi)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(!fi) return;
|
||||
|
||||
for(i = 0; i < fi->nsymm; ++i) free(fi->symm_store[i].d);
|
||||
free(fi->symm_store);
|
||||
|
||||
free(fi->x);
|
||||
free(fi->coeff);
|
||||
free(fi);
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct fir_filter_t*
|
||||
fir_filter_clone(const struct fir_filter_t* fi)
|
||||
{
|
||||
struct fir_filter_t* out = fir_filter_new(fi->coeff, fi->ncoeff, fi->symm);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double
|
||||
fir_filter(struct fir_filter_t* fi, double x)
|
||||
{
|
||||
int i, xpos, spos;
|
||||
double p, y = 0;
|
||||
|
||||
if(!fi->primed) {
|
||||
fi->primed = 1;
|
||||
for(i = 0; i < fi->ncoeff; ++i) fi->x[i] = x;
|
||||
for(i = 0; i < fi->nsymm; ++i) {
|
||||
for(spos = 0; spos < fi->symm_store[i].size; ++spos) {
|
||||
fi->symm_store[i].d[spos] = x * fi->coeff[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xpos = fi->xpos;
|
||||
fi->x[xpos] = x;
|
||||
|
||||
for(i = 0; i < fi->ncoeff; ++i) {
|
||||
p = fi->x[xpos] * fi->coeff[i];
|
||||
y += p;
|
||||
if(!xpos--) xpos += fi->ncoeff;
|
||||
|
||||
if(i < fi->nsymm) {
|
||||
spos = fi->symm_store[i].pos;
|
||||
fi->symm_store[i].d[spos] = p;
|
||||
if(++spos == fi->symm_store[i].size) spos = 0;
|
||||
fi->symm_store[i].pos = spos;
|
||||
}
|
||||
}
|
||||
|
||||
if(++fi->xpos == fi->ncoeff) fi->xpos = 0;
|
||||
|
||||
for(i = 0; i < fi->nsymm; ++i) {
|
||||
spos = fi->symm_store[i].pos;
|
||||
y += fi->symm_store[i].d[spos];
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* options for text editors
|
||||
vim: expandtab:ts=4:sw=4
|
||||
*/
|
|
@ -0,0 +1,35 @@
|
|||
/* libfir/src/libfir/100_fir.h
|
||||
*
|
||||
* Copyright: ©2014, Laurence Withers.
|
||||
* Author: Laurence Withers <l@lwithers.me.uk>
|
||||
* License: GPLv3
|
||||
*/
|
||||
|
||||
|
||||
|
||||
struct fir_filter_t;
|
||||
|
||||
|
||||
|
||||
enum fir_symmetry {
|
||||
fir_symmetry_none,
|
||||
fir_symmetry_odd,
|
||||
fir_symmetry_even,
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct fir_filter_t* fir_filter_new(const double* coeff, int ncoeff,
|
||||
enum fir_symmetry symm);
|
||||
|
||||
void fir_filter_free(struct fir_filter_t* fi);
|
||||
|
||||
struct fir_filter_t* fir_filter_clone(const struct fir_filter_t* fi);
|
||||
|
||||
double fir_filter(struct fir_filter_t* fi, double x);
|
||||
|
||||
|
||||
|
||||
/* options for text editors
|
||||
vim: expandtab:ts=4:sw=4
|
||||
*/
|
|
@ -0,0 +1,39 @@
|
|||
/* libfir/src/libfir/200_common_filters.c
|
||||
*
|
||||
* Copyright: ©2014, Laurence Withers.
|
||||
* Author: Laurence Withers <l@lwithers.me.uk>
|
||||
* License: GPLv3
|
||||
*/
|
||||
|
||||
|
||||
|
||||
struct fir_filter_t*
|
||||
fir_sinc_lowpass(int npoints, double corner)
|
||||
{
|
||||
double* coeff, t;
|
||||
int i, spoints;
|
||||
|
||||
/* find number of points after taking symmetry into account */
|
||||
spoints = (npoints + 1) / 2;
|
||||
coeff = alloca(sizeof(double) * spoints);
|
||||
|
||||
/* only fill out for t ≤ 0 */
|
||||
for(i = 0; i < spoints; ++i) {
|
||||
if((i * 2 + 1) == npoints) {
|
||||
coeff[i] = 1;
|
||||
} else {
|
||||
t = i + 0.5 - npoints * 0.5;
|
||||
t *= corner * 2;
|
||||
coeff[i] = sin(t) / t;
|
||||
}
|
||||
}
|
||||
|
||||
return fir_filter_new(coeff, spoints,
|
||||
(npoints & 1) ? fir_symmetry_odd : fir_symmetry_even);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* options for text editors
|
||||
vim: expandtab:ts=4:sw=4
|
||||
*/
|
|
@ -0,0 +1,16 @@
|
|||
/* libfir/src/libfir/200_common_filters.h
|
||||
*
|
||||
* Copyright: ©2014, Laurence Withers.
|
||||
* Author: Laurence Withers <l@lwithers.me.uk>
|
||||
* License: GPLv3
|
||||
*/
|
||||
|
||||
|
||||
|
||||
struct fir_filter_t* fir_sinc_lowpass(int npoints, double corner);
|
||||
|
||||
|
||||
|
||||
/* options for text editors
|
||||
vim: expandtab:ts=4:sw=4
|
||||
*/
|
|
@ -14,7 +14,7 @@ then
|
|||
libfir="obj/${libfir_BASE}.so.${SOMAJOR}.${SOMICRO}"
|
||||
libfir_DEP_CFLAGS="" # @TODO@ cflags
|
||||
libfir_DEP_LIBS="" # @TODO@ libs
|
||||
SO_EXTRA="${libfir_DEP_CFLAGS} ${libfir_DEP_LIBS} -lc \
|
||||
SO_EXTRA="${libfir_DEP_CFLAGS} ${libfir_DEP_LIBS} -lc -lm \
|
||||
-D_GNU_SOURCE -std=gnu99"
|
||||
|
||||
echo "Building library ${libfir}..."
|
||||
|
|
Loading…
Reference in New Issue