diff options
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | cmd_fir.c | 621 | ||||
-rw-r--r-- | cmd_fir.h | 15 | ||||
-rw-r--r-- | cmd_fir1p.c | 1 | ||||
-rw-r--r-- | cmd_rand.c | 19 | ||||
-rw-r--r-- | cmd_rand.h | 12 | ||||
-rw-r--r-- | cmd_rand_libc.c | 50 | ||||
-rw-r--r-- | cmd_rand_libc.h | 13 | ||||
-rw-r--r-- | config_cmds.h | 6 |
9 files changed, 743 insertions, 3 deletions
@@ -26,11 +26,14 @@ make: version $(CC) $(CFLAGS) cmd_botu.c -c $(CC) $(CFLAGS) cmd_fir1p.c -c $(CC) $(CFLAGS) sds.c -c + $(CC) $(CFLAGS) cmd_rand.c -c + $(CC) $(CFLAGS) cmd_rand_libc.c -c + $(CC) $(CFLAGS) cmd_fir.c -c $(CC) $(CFLAGS) tbl_qcmd.o mq_cmd.o mq_ntf.o buf.o mmm.o darray.o util.o sock_conn.o \ irc_parse.o mmm.c cmd_date.o cmd_uptime.o cmd_version.o cmd_ping.o cmd_loadavg.o \ - cmd_rusage.c cmd_cmd.o sha1.o cmd_sha1.o cmd_cookie.o cmd_botu.o cmd_fir1p.o sds.o \ - agni.c \ - -o $(PROJECT) -std=c11 -lrt + cmd_rusage.o cmd_cmd.o sha1.o cmd_sha1.o cmd_cookie.o cmd_botu.o cmd_fir1p.o sds.o \ + cmd_rand.o cmd_rand_libc.o cmd_fir.o agni.c \ + -o $(PROJECT) -std=c11 -lrt -lm version: #could have bug if commit message have somethign bad in it diff --git a/cmd_fir.c b/cmd_fir.c new file mode 100644 index 0000000..95e0b53 --- /dev/null +++ b/cmd_fir.c @@ -0,0 +1,621 @@ +#include "cmd_fir.h" + +#define pi 3.14159265 + +typedef struct filter_t +{ + double fs,fc1,fc2,beta; + int n,n1; + int wtype; + int type; + int nflag; +} filter_t; + +#define FILT_LP 1 +#define FILT_HP 2 +#define FILT_BP 3 +#define FILT_BS 4 +#define FILT_CHECK(X) (((X)>=FILT_LP)&&((X)<=FILT_BS)) + +#define FILT_WIN_RECT 1 +#define FILT_WIN_HAMM 2 +#define FILT_WIN_HANN 3 +#define FILT_WIN_BLCK 4 +#define FILT_WIN_KAIS 5 +#define FILT_WIN_CHECK(X) (((X)>=FILT_WIN_RECT)&&((X)<=FILT_WIN_KAIS)) + +void sincx1_(double fc, double *sinc_h, int n1, int parity); +int filter_spec_(filter_t *filt, int type, double fs, double fc1, double fc2, int wtype, double beta, int n); +void lowpass_highpass_(filter_t *filt, double *sinc_h); +void window_func_(filter_t *filt, double *win); +void filter_output_(filter_t *filt, double *h, double *hb); +double bessel(double x); + +void filter_calc(filter_t *filt, double *hc, int hc_sz); + + + +int filter_spec_(filter_t *filt, int type, double fs, double fc1, double fc2, int wtype, double beta, int n) +{ + + /*Check input params*/ + //check sample rate + if (fs < 0) + { + ERROR("ERROR fs\n"); + return -1; + } + filt->fs = fs; + + //check filter type + if (!FILT_CHECK(type)) + { + ENL(); + return -1; + } + filt->type = type; + + if ((filt->type==FILT_LP)||(filt->type==FILT_HP)) + { + //PRINT("%f %f\n",fc1, fs); + filt->fc1 = fc1/fs; //fc2 not used + } else if ((type==FILT_BS)||(type==FILT_BP)) + { + filt->fc1 = fc1/fs; + filt->fc2 = fc2/fs; + //PRINT("%f %f %f\n", fc1, fc2, fs); + } else + { + ENL(); + return -1; + } + + //window type used + if (FILT_WIN_CHECK(wtype)) + { + if (wtype == FILT_WIN_KAIS) + { + //beta for Kaiser window + filt->beta = beta; + } + } + filt->wtype = wtype; + + /* request filter length and determine whether it is odd or even + * for N even only N/2 coefficients need be calculated, and for N odd + * only (N+1)/2 because of the symmetry in h(n). + */ + + filt->n = n; + filt->n1 = n/2; + filt->nflag = 1; + if ((filt->n - 2*filt->n1)==1) + { + filt->nflag = 0; + filt->n1 = filt->n1+1; + } + return 0; +} + +//sinc_h size as filt->n1 size +void lowpass_highpass_(filter_t *filt, double *h) +{ + int j; + + sincx1_(filt->fc1, h, filt->n1, filt->nflag); + if (filt->type == FILT_HP) + { + h[0]=1-h[0]; + for (j=0;j<filt->n1;++j) + { + h[j] = -h[j]; + //printf("%f ",sinc_h[j]); + } + } + +} + + +void bandpass_bandstop_(filter_t *filt, double *sinc_h, double *h_bp) +{ + int j; + + double fc; + + fc = filt->fc2; + sincx1_(fc, sinc_h, filt->n1, filt->nflag); + for (j=0; j<filt->n1;++j) + { + h_bp[j] = sinc_h[j]; + } + + fc = filt->fc1; + sincx1_(fc, sinc_h, filt->n1, filt->nflag); + for (j=0;j<filt->n1;++j) + { + sinc_h[j] = h_bp[j] - sinc_h[j]; + } + + if (filt->type == FILT_BS) + { + sinc_h[0] = 1 - sinc_h[0]; + for (j=1; j<filt->n1; ++j) + { + sinc_h[j] = -sinc_h[j]; + } + } +} + +/*---------------------------------------------------------------------- +* function to calculate sincx: 2FC * sin(nwc)/nwc +*/ +void sincx1_(double fc, double *h, int n1, int parity) +{ + int i,j; + double omega, p; + + omega=2*pi*fc; + h[0]=2*fc; + i=1; + if(parity==1) + { /* check for N even */ + i=0; + } + + for(j=i; j<n1; j++) + { + p=parity*0.5+j; + h[j]=2*fc*sin(omega*p)/(omega*p); + } +} + + +void window_func_(filter_t *filt, double *win) +{ + int j; + double bd,p,rm,bn,x1; + + switch (filt->wtype) + { + case FILT_WIN_RECT: + for (j=0; j<filt->n1; ++j) + { + win[j]=1.0; + } + break; + case FILT_WIN_HAMM: + for (j=0; j<filt->n1; ++j) + { + p=filt->nflag*0.5+j; + win[j] = 0.54+(1-0.54)*cos(2*pi*p/filt->n); + } + break; + case FILT_WIN_HANN: + for (j=0; j<filt->n1; ++j) + { + p = filt->nflag*0.5 + j; + win[j] = 0.5+(1-0.5)*cos(2*pi*p/filt->n); + } + break; + case FILT_WIN_BLCK: + for (j=0; j<filt->n1; ++j) + { + p = filt->nflag*0.5 + j; + win[j] = 0.42 + + 0.5*cos(2*pi*p/(filt->n-1)) + + 0.08*cos(4*pi*p/(filt->n-1)); + } + break; + case FILT_WIN_KAIS: + x1 = filt->beta; + bd = bessel(x1); + for (j=0; j<filt->n1; ++j) + { + p = filt->nflag*0.5 + j; + rm = 2*p/(filt->n); + rm = rm*rm; + x1 = filt->beta * sqrt(1-rm); + bn = bessel(x1); + win[j] = bn/bd; + } + break; + default: + printf("Unknown window type %d\n", filt->wtype); + } +} + +/* +* +*/ +double bessel(double x) +{ + double y,t,t1,e,de,sde; + int i; + + y=x/2; + t=1.E-08; e=1; de=1; + for(i=1; i <25; ++i){ + t1=(double) i; + de=de*y/t1; + sde=de*de; + e=e+sde; + if((e*t-sde) > 0.0) + return(e); + } + ENL(); + return 0.0; +} + + +void filter_output_(filter_t *filt, double *h, double *hb) +{ + int j; + + double fs,fc,fc1,fc2; + + fs = filt->fs; + fc = filt->fc1 * filt->fs; + fc1 = filt->fc1 * filt->fs; + fc2 = filt->fc2 * filt->fs; + + switch(filt->type) + { + case FILT_LP: + printf("lowpass filter \n"); + printf("sampling frequency:\t%f\n", fs); + printf("cutoff frequency:\t%f\n", fc); + break; + case FILT_HP: + printf("highpass filter \n"); + printf("sampling frequency:\t%f\n", fs); + printf("cutoff frequency:\t%f\n", fc); + break; + case FILT_BP: + printf("bandpass filter \n"); + printf("sampling frequency:\t%f\n", fs); + printf("cutoff frequencies:\t%f\t%f\n", fc1, fc2); + break; + case FILT_BS: + printf("bandstop filter \n"); + printf("sampling frequency:\t%f\n", fs); + printf("cutoff frequencies:\t%f\t%f\n", fc1, fc2); + break; + } + printf("\n"); + + switch(filt->wtype) + { + case 1: + printf("Rectangular window \n"); + break; + case 2: + printf("Hamming window \n"); + break; + case 3: + printf("Hanning window \n"); + break; + case 4: + printf("Blackman window \n"); + break; + case 5: + printf("Kaiser window \n"); + break; + } + printf("\n"); + + printf("Impulse response coefficients\n"); + printf("\n"); + for (j=0;j<filt->n1;++j) + { + printf("h[%2d",j); + printf("] =\t%15.5e\t",h[filt->n1-j-1]); + printf(" = h[%2d",filt->n-j-1); + printf("]\n"); + hb[j]=h[filt->n1-j-1]; + hb[filt->n-j-1]=hb[j]; + } +} + +void filter_calc(filter_t *filt, double *hc, int hc_sz) +{ + int i; + double *h=NULL,*w=NULL,*hb=NULL; + filter_t loc_filt; + + memset(&loc_filt, 0, sizeof(filter_t)); + + if (filt == NULL) + { + ENL(); + return; + } + + if (hc == NULL) + { + ENL(); + return; + } + + if (hc_sz<=0) + { + ENL(); + return; + } + + //set internal structure value, precalculate coefficients + filter_spec_(&loc_filt, filt->type, filt->fs, filt->fc1, filt->fc2, filt->wtype, filt->beta, filt->n); + + h = malloc(sizeof(double) * loc_filt.n1); + if (h==NULL) + { + ENL(); + } + memset(h, 0, sizeof(double) * loc_filt.n1); + + hb = malloc(sizeof(double) * loc_filt.n); + if (hb==NULL) + { + ENL(); + } + memset(hb, 0, sizeof(double) * loc_filt.n); + + + + w = malloc(sizeof(double) * loc_filt.n1); + if (w==NULL) + { + ENL(); + } + memset(w, 0, sizeof(double) * loc_filt.n1); + + if ( + (loc_filt.type == FILT_LP) + || (loc_filt.type == FILT_HP) + ) + { + lowpass_highpass_(&loc_filt, h); + } else if ( + (loc_filt.type == FILT_BP) + || (loc_filt.type == FILT_BS) + ) + { + bandpass_bandstop_(&loc_filt, h, hb); + } else + { + ENL(); + } + + window_func_(&loc_filt, w); /* compute the window function */ + for(i=0; i < loc_filt.n1; i++) + { + h[i]=h[i]*w[i]; + } + //filter_output_(&loc_filt, h, hb); /* print the filter coefficients */ + + for (i=0; i<loc_filt.n1; i++) + { + if (i<hc_sz) + { + hc[i] = h[loc_filt.n1-i-1]; + + } + if ((loc_filt.n-i-1)<hc_sz) + { + hc[loc_filt.n-i-1] = h[loc_filt.n1-i-1]; + } + } + free(h); + free(w); + free(hb); + + return; +} + + +void *cmd_fir(void *data) +{ + char *ret = NULL; + int i=0,j=0; + + int count; + sds params; + sds out_result; + sds *tokens; + + double arg_fs; + int arg_ftype; + double arg_fc1; + double arg_fc2; + double arg_beta; + int arg_wtype; + int arg_n; + double *lp_coef; + filter_t filt; + + printf("FIR\n"); + + if (data == NULL) + { + ret = alloc_new_str("FIR [FTYPE] [FS] [FC1] [FC2] [WTYPE] [BETA] [N]\n"); + return ret; + } + + //prepare arguments + params = sdsnew(data); + out_result = sdsempty(); + tokens = sdssplitargs(params, &count); + + if (count == 1) + { + if (strncmp(tokens[0],"HELP",4)==0) + { + ret = alloc_new_str("FIR [Ftype=LP|HP|BP|BS] [Fs=1...1000000] [Fc1=1...1000000] [Fc2=1...1000000] [Wtype=RECT|HAMM|HANN|BLCK|KAIS] [beta=0.0...1.0] [n=1...63]\n"); + } else if (strncmp(tokens[0],"FIR",3)==0) + { + ret = alloc_new_str("Finite response filter\n"); + } else if (strncmp(tokens[0],"Ftype",5)==0) + { + ret = alloc_new_str("Filter type\n"); + } else if (strncmp(tokens[0],"Fs",2)==0) + { + ret = alloc_new_str("Sampling frequency\n"); + } else if (strncmp(tokens[0],"Fc1",3)==0) + { + ret = alloc_new_str("First cuttoff frequency\n"); + } else if (strncmp(tokens[0],"Fc2",3)==0) + { + ret = alloc_new_str("Second cuttoff frequency\n"); + } else if (strncmp(tokens[0],"Wtype",5)==0) + { + ret = alloc_new_str("Window type used to calculare\n"); + } else if (strncmp(tokens[0],"beta",4)==0) + { + ret = alloc_new_str("coeficient used with Kaiser window\n"); + } else if (strncmp(tokens[0],"n",1)==0) + { + ret = alloc_new_str("n-order filter\n"); + } + sdsfree(params); + sdsfree(out_result); + sdsfreesplitres(tokens, count); + return ret; + } + + if (count != 7) + { + PRINT("count = %d\n", count); + ret = alloc_new_str("Need 7 arguments\nFIR [FTYPE] [FS] [FC1] [FC2] [WTYPE] [BETA] [N]\n"); + sdsfree(params); + sdsfree(out_result); + sdsfreesplitres(tokens, count); + return ret; + } + + PNL(); + arg_fs = atof(tokens[1]); + if (arg_fs>1000000) + { + arg_fs = 1000000; //1Mhz should be enought + } else if (arg_fs<2) + { + arg_fs = 2; + } + + PNL(); + arg_fc1 = atof(tokens[2]); + if (arg_fc1>1000000.0) + { + arg_fc1 = 1000000.0; + } else if (arg_fc1<1.0) + { + arg_fc1 = 1.0; + } + + PNL(); + arg_fc1 = atof(tokens[2]); + if (arg_fc1>1000000.0) + { + arg_fc1 = 1000000.0; + } else if (arg_fs<1.0) + { + arg_fc1 = 1.0; + } + + PNL(); + arg_n = atoi(tokens[6]); + if (arg_n>63) + { + arg_n = 63; + } else if (arg_n<1) + { + arg_n = 1; + } + + PNL(); + arg_beta = atof(tokens[5]); + if (arg_beta > 1.0) + { + arg_beta = 1.0; + } else if (arg_beta < 0.0) + { + arg_beta = 0.0; + } + + PNL(); + + if (strncmp(tokens[4],"RECT",4)==0) + { + arg_wtype = FILT_WIN_RECT; + } else if (strncmp(tokens[4],"HAMM",4)==0) + { + arg_wtype = FILT_WIN_HAMM; + } else if (strncmp(tokens[4],"HANN",4)==0) + { + arg_wtype = FILT_WIN_HANN; + } else if (strncmp(tokens[4],"BLCK",4)==0) + { + arg_wtype = FILT_WIN_BLCK; + } else if (strncmp(tokens[4],"KAIS",4)==0) + { + arg_wtype = FILT_WIN_BLCK; + } else + { + arg_wtype = FILT_WIN_RECT; + } + + PNL(); + if (strncmp(tokens[0],"LP",2)==0) + { + arg_ftype = FILT_LP; + } else if (strncmp(tokens[0],"HP",2)==0) + { + arg_ftype = FILT_HP; + } else if (strncmp(tokens[0],"BP",2)==0) + { + arg_ftype = FILT_BP; + } else if (strncmp(tokens[0],"BS",2)==0) + { + arg_ftype = FILT_BS; + } else + { + arg_ftype = FILT_LP; + } + + PNL(); + //calculate + lp_coef = malloc(sizeof(double)*arg_n); + memset(lp_coef, 0, sizeof(double)*arg_n); + + PNL(); + filt.type = arg_ftype; + filt.fs = arg_fs; + filt.fc1 = arg_fc1; + filt.fc2 = arg_fc2; + filt.wtype = arg_wtype; + filt.n = arg_n; + filt.beta = arg_beta; + + PNL(); + filter_calc(&filt, lp_coef, arg_n); + + + //prepare output + for (i=0;i<arg_n;i++) + { + char str_double[16]; + snprintf(str_double, 16, "%.3f ", lp_coef[i]); + out_result = sdscat(out_result, str_double); + } + out_result = sdscat(out_result, "\n"); + + ret = alloc_new_str(out_result); + + PNL(); + + free(lp_coef); + sdsfree(params); + sdsfree(out_result); + sdsfreesplitres(tokens, count); + + return ret; +}
\ No newline at end of file diff --git a/cmd_fir.h b/cmd_fir.h new file mode 100644 index 0000000..46815a7 --- /dev/null +++ b/cmd_fir.h @@ -0,0 +1,15 @@ +#ifndef __CMD_FIR_H +#define __CMD_FIR_H + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> + +#include "sds.h" +#include "util.h" +#include "debug.h" + +void *cmd_fir(void *data); + +#endif
\ No newline at end of file diff --git a/cmd_fir1p.c b/cmd_fir1p.c index d56eb1c..b011719 100644 --- a/cmd_fir1p.c +++ b/cmd_fir1p.c @@ -75,6 +75,7 @@ void *cmd_fir1p(void *data) for (i=0;i<count;i++) { + //cut to max size 512 char str_double[16]; snprintf(str_double, 16, "%.3f ", output[i]); out_result = sdscat(out_result, str_double); diff --git a/cmd_rand.c b/cmd_rand.c new file mode 100644 index 0000000..58f2efe --- /dev/null +++ b/cmd_rand.c @@ -0,0 +1,19 @@ +#include "cmd_rand.h" + + +void *cmd_rand(void *data) +{ + char *ret = NULL; + int fret=-1; + + const int buf_size = 128; + char buf[buf_size+1]; + + printf("RAND\n"); + + + snprintf(buf, buf_size, "4"); + ret = alloc_new_str(buf); + + return ret; +} diff --git a/cmd_rand.h b/cmd_rand.h new file mode 100644 index 0000000..14f5c7e --- /dev/null +++ b/cmd_rand.h @@ -0,0 +1,12 @@ +#ifndef __CMD_RAND_H +#define __CMD_RAND_H + +#include <stdlib.h> +#include <stdio.h> + +#include "util.h" +#include "debug.h" + +void *cmd_rand(void *data); + +#endif
\ No newline at end of file diff --git a/cmd_rand_libc.c b/cmd_rand_libc.c new file mode 100644 index 0000000..d72bc45 --- /dev/null +++ b/cmd_rand_libc.c @@ -0,0 +1,50 @@ +#include "cmd_rand_libc.h" + + +void *cmd_rand_libc(void *data) +{ + char *ret = NULL; + int fret=-1; + + const int buf_size = 128; + char buf[buf_size+1]; + + printf("RAND LIBC\n"); + + int i; + int count; + int rand_val; + sds params; + sds out_result; + sds *tokens; + + if (data == NULL) + { + rand_val = rand(); + snprintf(buf, buf_size, "%d", rand_val); + } else { + //cut output to 512 + char str_integer[16]; + int rand_state; + + params = sdsnew(data); + out_result = sdsempty(); + tokens = sdssplitargs(params, &count); + for (i=0;i<count;i++) + { + rand_state = atoi(tokens[i]); + snprintf(str_integer, 16, "%d ", rand_r(&rand_state)); + out_result = sdscat(out_result, str_integer); + } + out_result = sdscat(out_result,"\n"); + snprintf(buf, buf_size, "%s", out_result); + + sdsfree(params); + sdsfree(out_result); + sdsfreesplitres(tokens, count); + } + + ret = alloc_new_str(buf); + + return ret; +} diff --git a/cmd_rand_libc.h b/cmd_rand_libc.h new file mode 100644 index 0000000..42fb1a1 --- /dev/null +++ b/cmd_rand_libc.h @@ -0,0 +1,13 @@ +#ifndef __CMD_RAND_LIBC_H +#define __CMD_RAND_LIBC_H + +#include <stdlib.h> +#include <stdio.h> + +#include "sds.h" +#include "util.h" +#include "debug.h" + +void *cmd_rand_libc(void *data); + +#endif
\ No newline at end of file diff --git a/config_cmds.h b/config_cmds.h index 1e22d79..c206ca6 100644 --- a/config_cmds.h +++ b/config_cmds.h @@ -20,6 +20,9 @@ typedef struct single_cmd_def #include "cmd_cookie.h" #include "cmd_botu.h" #include "cmd_fir1p.h" +#include "cmd_rand.h" +#include "cmd_rand_libc.h" +#include "cmd_fir.h" //some commands have aliases for compat with some developerslv bots //nothing else comaptible will be added, as its not about "standarts" @@ -36,6 +39,9 @@ single_cmd_def confgi_cmd_list[] = {"COOKIE",cmd_cookie}, {"BOTU",cmd_botu}, {"!uptime",cmd_botu}, {"FIR1P",cmd_fir1p}, + {"RAND",cmd_rand}, + {"RANDC",cmd_rand_libc}, + {"FIR",cmd_fir}, {NULL,NULL} }; |