Jump to content

Apply a digital filter (direct form II transposed): Difference between revisions

Added C implementation.
(Added C implementation.)
Line 8:
The signal that needs filtering is the following vector: [-0.917843918645, 0.141984778794, 1.20536903482, 0.190286794412, -0.662370894973, -1.00700480494, -0.404707073677 ,0.800482325044, 0.743500089861, 1.01090520172, 0.741527555207, 0.277841675195, 0.400833448236, -0.2085993586, -0.172842103641, -0.134316096293, 0.0259303398477, 0.490105989562, 0.549391221511, 0.9047198589]
 
=={{header|C}}==
Given the number of values a coefficient or signal vector can have and the number of digits, this implementation reads data from a file and prints it to the console if no output file is specified or writes to the specified output file. Usage printed on incorrect invocation.
<lang C>
/*Abhishek Ghosh, 25th October 2017*/
 
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
 
#define MAX_LEN 1000
 
typedef struct{
float* values;
int size;
}vector;
 
vector extractVector(char* str){
vector coeff;
int i=0,count = 1;
char* token;
while(str[i]!=00){
if(str[i++]==' ')
count++;
}
coeff.values = (float*)malloc(count*sizeof(float));
coeff.size = count;
token = strtok(str," ");
i = 0;
while(token!=NULL){
coeff.values[i++] = atof(token);
token = strtok(NULL," ");
}
return coeff;
}
 
vector processSignalFile(char* fileName){
int i,j;
float sum;
char str[MAX_LEN];
vector coeff1,coeff2,signal,filteredSignal;
FILE* fp = fopen(fileName,"r");
fgets(str,MAX_LEN,fp);
coeff1 = extractVector(str);
fgets(str,MAX_LEN,fp);
coeff2 = extractVector(str);
fgets(str,MAX_LEN,fp);
signal = extractVector(str);
filteredSignal.values = (float*)calloc(signal.size,sizeof(float));
filteredSignal.size = signal.size;
for(i=0;i<signal.size;i++){
sum = 0;
for(j=0;j<coeff2.size;j++){
if(i-j>=0)
sum += coeff2.values[j]*signal.values[i-j];
}
for(j=0;j<coeff1.size;j++){
if(i-j>=0)
sum -= coeff1.values[j]*filteredSignal.values[i-j];
}
sum /= coeff1.values[0];
filteredSignal.values[i] = sum;
}
return filteredSignal;
}
 
void printVector(vector v, char* outputFile){
int i;
if(outputFile==NULL){
printf("[");
for(i=0;i<v.size;i++)
printf("%.12f, ",v.values[i]);
printf("\b\b]");
}
else{
FILE* fp = fopen(outputFile,"w");
for(i=0;i<v.size-1;i++)
fprintf(fp,"%.12f, ",v.values[i]);
fprintf(fp,"%.12f",v.values[i]);
fclose(fp);
}
}
 
int main(int argC,char* argV[])
{
char *str;
if(argC<2||argC>3)
printf("Usage : %s <name of signal data file and optional output file.>",argV[0]);
else{
if(argC!=2){
str = (char*)malloc((strlen(argV[2]) + strlen(str) + 1)*sizeof(char));
strcpy(str,"written to ");
}
printf("Filtered signal %s",(argC==2)?"is:\n":strcat(str,argV[2]));
printVector(processSignalFile(argV[1]),argV[2]);
}
return 0;
}
</lang>
Input file, 3 lines containing first ( a ) and second ( b ) coefficient followed by the signal, all values should be separated by a single space:
<pre>
1.00000000 -2.77555756e-16 3.33333333e-01 -1.85037171e-17
0.16666667 0.5 0.5 0.16666667
-0.917843918645 0.141984778794 1.20536903482 0.190286794412 -0.662370894973 -1.00700480494 -0.404707073677 0.800482325044 0.743500089861 1.01090520172 0.741527555207 0.277841675195 0.400833448236 -0.2085993586 -0.172842103641 -0.134316096293 0.0259303398477 0.490105989562 0.549391221511 0.9047198589
</pre>
Invocation and output for writing to file :
<pre>
C:\rosettaCode>filterSignal.exe signalData.txt signalOut1.txt
Filtered signal written to signalOut1.txt
</pre>
Output file :
<pre>
-0.152973994613, -0.435257852077, -0.136043429375, 0.697503268719, 0.656444668770, -0.435482472181, -1.089239478111, -0.537676513195, 0.517050027847, 1.052249789238, 0.961854279041, 0.695690035820, 0.424356281757, 0.196262255311, -0.027835110202, -0.211721926928, -0.174745559692, 0.069258414209, 0.385445863008, 0.651770770550
</pre>
=={{header|C++}}==
 
503

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.