WIP
This commit is contained in:
		
							parent
							
								
									679b37dc35
								
							
						
					
					
						commit
						d42f63388e
					
				| 
						 | 
					@ -8,6 +8,10 @@
 | 
				
			||||||
#include "fir.h"
 | 
					#include "fir.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Below are all the includes used throughout the library. */
 | 
					/* 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
 | 
					/* options for text editors
 | 
				
			||||||
vim: expandtab:ts=4:sw=4
 | 
					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="obj/${libfir_BASE}.so.${SOMAJOR}.${SOMICRO}"
 | 
				
			||||||
    libfir_DEP_CFLAGS="" # @TODO@ cflags
 | 
					    libfir_DEP_CFLAGS="" # @TODO@ cflags
 | 
				
			||||||
    libfir_DEP_LIBS="" # @TODO@ libs
 | 
					    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"
 | 
					        -D_GNU_SOURCE -std=gnu99"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    echo "Building library ${libfir}..."
 | 
					    echo "Building library ${libfir}..."
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue