diff options
author | Arturs Artamonovs <arturs.artamonovs@protonmail.com> | 2021-07-15 09:40:35 +0100 |
---|---|---|
committer | Arturs Artamonovs <arturs.artamonovs@protonmail.com> | 2021-07-15 09:40:35 +0100 |
commit | e2d7791085b71212ac0dc859bdab132e05f76ae7 (patch) | |
tree | e324e354e2fc2b6f6b75352fd5752303b1edb8f5 /FIR | |
parent | 845dda7e5d0b8a19473166408ed138f0cb9d04ca (diff) | |
download | WasmAudio-e2d7791085b71212ac0dc859bdab132e05f76ae7.tar.gz WasmAudio-e2d7791085b71212ac0dc859bdab132e05f76ae7.zip |
Added fir filter code and functions for buffer conversion
Diffstat (limited to 'FIR')
-rw-r--r-- | FIR/firmath.c | 247 | ||||
-rw-r--r-- | FIR/firmath.h | 43 |
2 files changed, 290 insertions, 0 deletions
diff --git a/FIR/firmath.c b/FIR/firmath.c new file mode 100644 index 0000000..3fdf20b --- /dev/null +++ b/FIR/firmath.c @@ -0,0 +1,247 @@ +// +// firmath.c +// FIR_rect_win +// +// Created by Jacky Jack on 04/07/2021. +// + +#include "firmath.h" + +/* +void window_func_rect(double *w, int N1) { + int j; + + for (j=0;j<N1;j++) { + w[j] = 1.0; + } +} +*/ + +void fir_init(fir_t *fir, uint32_t taps) { + int i; + for (i=0;i<taps;i++) { + fir->fir_coef[i] = (double)0.0; + } + fir->num_taps = taps; +} + + +void firw_init(firw_t *fir_win, uint32_t taps) { + int i; + for (i=0;i<taps;i++) { + fir_win->win_coef[i] = (double)0.0; + } + fir_win->num_taps = taps; +} + + +double math_sinx(double x) { + if (x>-1.0E-5 && x < 1.0E-5) return (1.0); + return sin(x)/x; +} + +void fir_sinc_lp(fir_t *fir, double omega_c) { + int i; + double arg=0.0; + //should set 2fc?! + printf("omega_c=%f\n",omega_c); + for (i=0;i<fir->num_taps;i++) { + arg = (double)i-(double)(fir->num_taps-1)/2.0; + fir->fir_coef[i] = omega_c * math_sinx(omega_c*arg*M_PI); + } +} + +void fir_sinc_hp(fir_t *fir, double omega_c) { + int i; + double arg=0.0; + int even = fir->num_taps%2 ? 0: 1; + + //should set 2fc?! + printf("omega_c=%f\n",omega_c); + if (even) { + for (i=0;i<fir->num_taps;i++) { + arg = (double)i-(double)(fir->num_taps-1)/2.0; + if (arg == 0.0) { + fir->fir_coef[i] = 0.0; + } else { + //from IOWA + fir->fir_coef[i] = cos(omega_c*arg*M_PI)/M_PI/arg + cos(arg*M_PI); + } + } + } else { + for (i=0;i<fir->num_taps;i++) { + arg = (double)i-(double)(fir->num_taps-1)/2.0; + fir->fir_coef[i] = math_sinx(arg*M_PI)-omega_c * math_sinx(omega_c*arg*M_PI); + } + } +} + +void fir_sinc_bp(fir_t *fir, double omega_c1, double omega_c2) { + int i; + double arg=0.0; + //should set 2fc?! + printf("omega_c1=%f\n",omega_c1); + printf("omega_c2=%f\n",omega_c2); + for (i=0;i<fir->num_taps;i++) { + arg = (double)i-(double)(fir->num_taps-1)/2.0; + if (arg==0.0) { + fir->fir_coef[i] = 0.0; + } else { + //fir->fir_coef[i] = math_sinx(arg*M_PI) - omega_c2 * math_sinx(omega_c2*arg*M_PI) - omega_c1 * math_sinx(omega_c1*arg*M_PI); + fir->fir_coef[i] = (cos(omega_c1*arg*M_PI) - cos(omega_c2*arg*M_PI))/M_PI/arg; + } + } +} + +void fir_sinc_bs(fir_t *fir, double omega_c1, double omega_c2) { + int i; + double arg=0.0; + //should set 2fc?! + printf("omega_c1=%f\n",omega_c1); + printf("omega_c2=%f\n",omega_c2); + for (i=0;i<fir->num_taps;i++) { + arg = (double)i-(double)(fir->num_taps-1)/2.0; + if (arg==0.0) { + fir->fir_coef[i] = 0.0; + } else { + //fir->fir_coef[i] = math_sinx(arg*M_PI) - omega_c2 * math_sinx(omega_c2*arg*M_PI) - omega_c1 * math_sinx(omega_c1*arg*M_PI); + fir->fir_coef[i] = math_sinx(arg*M_PI) - omega_c2*math_sinx(omega_c2*arg*M_PI) - omega_c1*math_sinx(omega_c1*arg*M_PI); + } + } +} + +void fir_convolute(fir_t *fir,firw_t *firw) { + int i=0; + for (i=0;i<fir->num_taps;i++) { + fir->fir_coef[i] = fir->fir_coef[i]*firw->win_coef[i]; + } +} + + +void firw_rect(firw_t *fir_win) { + int i; + int n1 = fir_win->num_taps/2; + int even = fir_win->num_taps%2 ? 0: 1; + + if (even) n1+=1; + + for (i=0;i<n1;i++) { + fir_win->win_coef[i] = 1.0; + } + + for (i=0;i<n1;i++) { + fir_win->win_coef[fir_win->num_taps-1-i] = fir_win->win_coef[i]; + } + +} + + +void firw_hamming(firw_t *fir_win) { + int i; + double dN=0; + double arg=0; + //double p=0; + //double arg=0; + + int n1 = fir_win->num_taps/2; + int even = fir_win->num_taps%2 ? 0: 1; + if (!even) n1+=1; + dN = fir_win->num_taps +1; + + for (i=0;i<n1;i++) { + //arg = (double)i-(double)(fir_win->num_taps-1)/2.0; + //fir_win->win_coef[i] = 0.54+(1-0.54)*cos(2*M_PI*arg/n1); + + //fir_win->win_coef[i] = 0.54+(1-0.54)*cos(2*M_PI*i/n1); + arg = (double)i-(double)(fir_win->num_taps-1)/2.0; + fir_win->win_coef[i] = 0.54+0.46*cos(2*M_PI*arg/fir_win->num_taps); + + } + //fold + for (i=0;i<n1;i++) { + //arg = (double)i-(double)(fir_win->num_taps-1)/2.0; + //fir_win->win_coef[i] = 0.54+(1-0.54)*cos(2*M_PI*arg/n1); + + fir_win->win_coef[fir_win->num_taps-1-i] = fir_win->win_coef[i]; + } + +} + + +void firw_hanning(firw_t *fir_win) { + int i; + double dN=0; + double arg=0; + + int n1 = fir_win->num_taps/2; + int even = fir_win->num_taps%2 ? 0: 1; + if (!even) n1+=1; + dN = fir_win->num_taps +1; + + for (i=0;i<n1;i++) { + arg = (double)i-(double)(fir_win->num_taps-1)/2.0; + fir_win->win_coef[i] = 0.5+(1-0.5)*cos(2*M_PI*arg/fir_win->num_taps); + + } + //fold + for (i=0;i<n1;i++) { + fir_win->win_coef[fir_win->num_taps-1-i] = fir_win->win_coef[i]; + } +} + +void firw_blackman(firw_t *firw) { + int i; + double dN=0; + double arg=0; + + int n1 = firw->num_taps/2; + int even = firw->num_taps%2 ? 0: 1; + if (!even) n1+=1; + dN = firw->num_taps +1; + + for (i=0;i<n1;i++) { + arg = (double)i-(double)(firw->num_taps-1)/2.0; + /* + firw->win_coef[i] = 0.42 + +0.50*cos(2*M_PI*arg/(firw->num_taps)) + +0.08*cos(4*M_PI*arg/(firw->num_taps)); + */ + firw->win_coef[i] = 0.42 + +0.50*cos(2*M_PI*arg/(firw->num_taps-1)) + +0.08*cos(4*M_PI*arg/(firw->num_taps-1)); + + } + //fold + for (i=0;i<n1;i++) { + firw->win_coef[firw->num_taps-1-i] = firw->win_coef[i]; + } +} + +void fir_print_matlab(fir_t *fir) { + int i; + printf("f=[\n"); + for (i=0;i<fir->num_taps;i++) { + printf("%f\n",fir->fir_coef[i]); + } + printf("];\n"); +} + +void firw_print_matlab(firw_t *firw) { + int i; + printf("w=[\n"); + for (i=0;i<firw->num_taps;i++) { + printf("%f\n",firw->win_coef[i]); + } + printf("];\n"); +} + + +void fir_print_c(fir_t *fir) { + int i; + printf("double f=[\n"); + for (i=0;i<fir->num_taps;i++) { + printf("%f,\n",fir->fir_coef[i]); + } + printf("];\n"); +} + diff --git a/FIR/firmath.h b/FIR/firmath.h new file mode 100644 index 0000000..3540a98 --- /dev/null +++ b/FIR/firmath.h @@ -0,0 +1,43 @@ +// +// firmath.h +// FIR_rect_win +// +// Created by Jacky Jack on 04/07/2021. +// + +#ifndef firmath_h +#define firmath_h + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <math.h> + +typedef struct fir_t { + uint32_t num_taps; + double *fir_coef; +} fir_t; + +typedef struct firw_t { + uint32_t num_taps; + double *win_coef; +} firw_t; + +void fir_init(fir_t *fir, uint32_t taps); +void firw_init(firw_t *fir_win, uint32_t taps); + +double math_sinx(double x); +void fir_sinc_lp(fir_t *fir, double fc); +void fir_sinc_hp(fir_t *fir, double omega_c); +void fir_sinc_bp(fir_t *fir, double omega_c1, double omega_c2); +void fir_sinc_bs(fir_t *fir, double omega_c1, double omega_c2); +void fir_convolute(fir_t *fir,firw_t *fir_win); +void firw_rect(firw_t *firw); +void firw_hamming(firw_t *firw); +void firw_hanning(firw_t *firw); +void firw_blackman(firw_t *firw); +void fir_print_matlab(fir_t *fir); +void firw_print_matlab(firw_t *firw); +void fir_print_c(fir_t *fir); + +#endif /* firmath_h */ |