├── .gitignore ├── LICENSE ├── README.md ├── examples ├── fft_ifft │ └── fft_ifft.ino ├── fft_spectrum │ └── fft_spectrum.ino ├── fir │ └── fir.ino └── iir │ └── iir.ino ├── keywords.txt ├── library.properties ├── simpleDSP_Global.h ├── simpleDSP_fft.c ├── simpleDSP_fft.h ├── simpleDSP_fir.c ├── simpleDSP_fir.h ├── simpleDSP_iir.c ├── simpleDSP_iir.h └── test ├── Makefile ├── testFIR.c └── testIIR.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | *.smod 19 | 20 | # Compiled Static libraries 21 | *.lai 22 | *.la 23 | *.a 24 | *.lib 25 | 26 | # Executables 27 | *.exe 28 | *.out 29 | *.app 30 | 31 | \.vscode/ 32 | 33 | testFIR 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Mehmet Ozan Ünal 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SimpleDSP 2 | SimpleDSP is a basic DSP library which is for arduino and most of the microcontrollers which can be programmed in C/C++ 3 | 4 | ## Performance: 5 | Here is some examples for its performance. Actually it is not optimized for performance. Its main focuses are portability and education. 6 | 7 | ### Arduino Nano 8 | * FFT 16 points: 2 ms 9 | * FFT 32 points: 6 ms 10 | * FFT 64 points: 16 ms 11 | * fir filter 10 coeficients: 190 us 12 | * fir filter 23 coeficients: 453 us 13 | * fir filter 46 coeficients: 900 us 14 | 15 | 10 coeficients FIR filter can be run at 5khz max frequency on an Arduino Nano. 16 | 17 | ## Arduino Due 18 | * FFT 64 points: 2 ms 19 | * FFT 128 points: 6 ms 20 | * FFT 256 points: 10 ms 21 | 22 | 23 | ## Fast Fourier Transform (FFT) and Inverse Fast Fourier Transform (IFFT) 24 | 25 | [detailed info](https://en.m.wikipedia.org/wiki/Fast_Fourier_transform) 26 | 27 | ### Arduino Example 28 | 29 | FFT and IFFT functions require 2 arguments. 30 | data 31 | data lenght 32 | Do not forget to add `#include "simpleDSP_FFT.h"` 33 | 34 | [Full example for FFT and IFFT please refer here](/examples/fft_ifft/fft_ifft.ino) 35 | 36 | [FFT spectrum example](/examples/fft_spectrum/fft_spectrum.ino) 37 | 38 | ```cpp 39 | FFT(data,DATA_LEN); 40 | IFFT(data,DATA_LEN); 41 | calcTime = millis()-startTime; 42 | Serial.print("Total calculation time: "); 43 | Serial.println(calcTime); 44 | ``` 45 | 46 | ## FIR Filter 47 | 48 | ### Theory 49 | 50 | [detailed info](https://en.wikipedia.org/wiki/Finite_impulse_response) 51 | 52 | ### Arduino Example 53 | 54 | FIR is filter structure which keep delays and coeficients of filter. There are 2 public functions. `firInit` initiliazes the structure according to parameters and makes required memory allocations. Coeficients and its lenght are given as parameter to this function 55 | Do not forget to add `#include "simpleDSP_fir.h"` 56 | ```cpp 57 | void firInit(FIR *fir, int coefBLen, float *coefsB); 58 | float firFilt(FIR *fir, int input); 59 | ``` 60 | [FIR Full example](/examples/fir/fir.ino) 61 | ```cpp 62 | Serial.begin(9600); 63 | firInit(&fir1, 46, coef); 64 | Serial.println("FIR filter initiliaze finished"); 65 | float a; 66 | startTime = micros(); 67 | for (int i = 0; i < 255; i++) 68 | { 69 | a = firFilt(&fir1, input[i]); 70 | } 71 | calcTime = micros() - startTime; 72 | Serial.print("Total calculation time: "); 73 | Serial.println(calcTime); 74 | ``` 75 | 76 | ## IIR Filter 77 | 78 | ### Theory 79 | 80 | [detailed info](https://en.wikipedia.org/wiki/Infinite_impulse_response) 81 | 82 | ### Arduino Example 83 | 84 | IIR is filter structure which keep delays and coeficient of filter. There are 2 functions to implement IIR filter using SimpleDSP library. initIIR function is the constructor function for the filter. Filter coeficients for a and b should be given as arguments to this function. After init, filtIIR must be used as filtering function. This function requires 2 arguments. Object instance and data. It returns the filtered output. 85 | 86 | ```cpp 87 | void iirInit(IIR *iir, int coefBLen, float *coefsB, int coefALen, float *coefsA); 88 | float iirFilt(IIR *iir, int input); 89 | ``` 90 | Do not forget to add `#include "simpleDSP_iir.h"` to your code. 91 | 92 | [IIR Full example](/examples/iir/iir.ino) 93 | 94 | ```cpp 95 | Serial.begin(9600); 96 | iirInit(&iir1, 4, coefB, 4, coefA); 97 | Serial.println("IIR filter initiliaze finished"); 98 | float a; 99 | startTime = micros(); 100 | for (int i = 0; i < 255; i++) 101 | { 102 | a = iirFilt(&iir1, input[i]); 103 | } 104 | calcTime = micros() - startTime; 105 | Serial.print("Total calculation time: "); 106 | Serial.println(calcTime); 107 | ``` 108 | 109 | 110 | 111 | ## Octave Test Code 112 | 113 | This code create sample data and plot the signal and its FFT. The octave code only needed for testing of function. 114 | Create sample signal which is at 10 kHz sample rate and it is the combination of 3.2 kHz and 800 Hz sine waves. 115 | 116 | ```octave 117 | N=255; 118 | f1=800; 119 | f2=3200; 120 | fo=10000; 121 | for i=1:1:N 122 | x(i)=1000*cos(2*pi*f1*i/fo)+1000*cos(2*pi*f2*i/fo); 123 | printf("%d\n",x(i)); 124 | end 125 | ``` 126 | 127 | 128 | Calculate and plot x and FFT of x. For fft x axis values are calculated using `kor=(1:N)*fo/N;` 129 | ```octave 130 | plot(x); 131 | X=abs(FFT(x)); 132 | figure; 133 | kor=(1:N)*fo/N; 134 | plot(kor,X); 135 | ``` 136 | 137 | **Output from octave** 138 | 139 | Graph of Raw Signal 140 | 141 | ![inputa](https://cloud.githubusercontent.com/assets/13440502/22374756/305a1d4e-e4b0-11e6-821a-9213b4f8a136.png) 142 | 143 | Graph of FFT Signal 144 | 145 | ![inputf](https://cloud.githubusercontent.com/assets/13440502/22374762/3abf9eee-e4b0-11e6-8e26-c0758e6c13a3.png) 146 | 147 | [you can use octave from here](octave-online.net) 148 | 149 | ### Filter Design Using Octave 150 | 151 | output of fir functions can be used as filter coeficients 152 | 153 | [Resource for FIR](https://octave.sourceforge.io/signal/function/fir1.html) 154 | 155 | Examples: 156 | 157 | ``` 158 | freqz (fir1 (40, 0.3)); 159 | freqz (fir1 (15, [0.2, 0.5], "stop")); # note the zero-crossing at 0.1 160 | freqz (fir1 (15, [0.2, 0.5], "stop", "noscale")); 161 | ``` 162 | 163 | ``` 164 | figure 165 | b= fir1 (20, 0.3, "low"); 166 | y = filter(b,1,x); 167 | plot(y) 168 | 169 | ``` 170 | 171 | filter frequency response 172 | 173 | ![function reference fir1](https://cloud.githubusercontent.com/assets/13440502/22388029/20f5a6fc-e4e7-11e6-99ed-885fe116be1d.png) 174 | 175 | [Resource for IIR](https://octave.sourceforge.io/signal/function/butter.html) 176 | 177 | 178 | 179 | ```octave 180 | figure 181 | [b, a] = butter(3, 0.3, "low"); 182 | y = filter(b,a,x); 183 | plot(y) 184 | ``` 185 | 186 | ```shell 187 | octave:> b 188 | b = 189 | 190 | 0.049533 0.1486 0.1486 0.049533 191 | octave:> a 192 | a = 193 | 194 | 1.00000 -1.16192 0.69594 -0.13776 195 | 196 | ``` 197 | 198 | 199 | **Outputs after filtering** 200 | 201 | 202 | Time Domain Signal 203 | 204 | ![output](https://cloud.githubusercontent.com/assets/13440502/22374514/24a63a88-e4af-11e6-8bd8-b7fa703bd459.png) 205 | 206 | FFT of Output Signal 207 | 208 | ![outputf](https://cloud.githubusercontent.com/assets/13440502/22374645/b0cbd266-e4af-11e6-9266-32aafec12986.png) 209 | 210 | 211 | 212 | -------------------------------------------------------------------------------- /examples/fft_ifft/fft_ifft.ino: -------------------------------------------------------------------------------- 1 | /*This is a signal sum of 800 hz and 3.2 khz sine waves 2 | which sampled in 10khz and 32 of this samples are 3 | create a data array. 4 | In this example first fft later inverse fft of 5 | signal calculated by arduino after the process output 6 | data will be same with input as we expected. 7 | */ 8 | 9 | #include "simpleDSP_fft.h" 10 | 11 | #define DATA_LEN 32 12 | 13 | COMPLEX data[DATA_LEN] = 14 | { 15 | 1380.30387436698, 16 | 0.0, 17 | 1411.95640122018, 18 | 0.0, 19 | 1509.33975623973, 20 | 0.0, 21 | 1680.97457720023, 22 | 0.0, 23 | 1945.62587488903, 24 | 0.0, 25 | 2341.52925818755, 26 | 0.0, 27 | 2948.35729012667, 28 | 0.0, 29 | 3949.59187366481, 30 | 0.0, 31 | 5862.08882614601, 32 | 0.0, 33 | 10877.1835331189, 34 | 0.0, 35 | 57733.7247892472, 36 | 0.0, 37 | 18723.4608750840, 38 | 0.0, 39 | 8298.42015377624, 40 | 0.0, 41 | 5427.67344196089, 42 | 0.0, 43 | 4083.68378659686, 44 | 0.0, 45 | 3304.24870517258, 46 | 0.0, 47 | 2795.46623030534, 48 | 0.0, 49 | 2437.40771712744, 50 | 0.0, 51 | 2172.01084844531, 52 | 0.0, 53 | 1967.76373917975, 54 | 0.0, 55 | 1806.10353733366, 56 | 0.0, 57 | 1675.40258778435, 58 | 0.0, 59 | 1568.02578276502, 60 | 0.0, 61 | 1478.77466877542, 62 | 0.0, 63 | 1404.01359504832, 64 | 0.0, 65 | 1341.15564969180, 66 | 0.0, 67 | 1288.35041545534, 68 | 0.0, 69 | 1244.29204061566, 70 | 0.0, 71 | 1208.10451406246, 72 | 0.0, 73 | 1179.28219795848, 74 | 0.0, 75 | 1157.67736663769, 76 | 0.0, 77 | 1143.53841226378, 78 | 0.0, 79 | }; 80 | 81 | long startTime; 82 | long calcTime; 83 | 84 | void setup() 85 | { 86 | Serial.begin(9600); 87 | startTime = millis(); 88 | FFT(data, DATA_LEN); 89 | IFFT(data, DATA_LEN); 90 | calcTime = millis() - startTime; 91 | Serial.print("Total calculation time: "); 92 | Serial.println(calcTime); 93 | for (int i = 0; i < DATA_LEN; i++) 94 | { 95 | Serial.print(data[i].real / DATA_LEN); 96 | Serial.print("\t\t"); 97 | Serial.println(data[i].imag / DATA_LEN); 98 | } 99 | } 100 | 101 | void loop() 102 | { 103 | // put your main code here, to run repeatedly: 104 | } -------------------------------------------------------------------------------- /examples/fft_spectrum/fft_spectrum.ino: -------------------------------------------------------------------------------- 1 | /*This is a signal sum of 800 hz and 3.2 khz sine waves 2 | which sampled in 10khz and 32 of this samples are 3 | create a data array. 4 | In this example spectrum of the signal showed using fft 5 | */ 6 | 7 | #include "simpleDSP_fft.h" 8 | 9 | #define DATA_LEN 64 10 | 11 | double data_magnitude[DATA_LEN]; 12 | 13 | COMPLEX data[DATA_LEN] = 14 | { 15 | 450.527388478791, 16 | 0.0, 17 | -101.597194769693, 18 | 0.0, 19 | 1031.37368065794, 20 | 0.0, 21 | -613.160606150798, 22 | 0.0, 23 | -1618.03398874990, 24 | 0.0, 25 | -115.808021270615, 26 | 0.0, 27 | -866.985966358939, 28 | 0.0, 29 | -1567.20047563694, 30 | 0.0, 31 | 541.587312835687, 32 | 0.0, 33 | 618.033988749895, 34 | 0.0, 35 | -263.146073893067, 36 | 0.0, 37 | 1504.40995610763, 38 | 0.0, 39 | 1504.40995610763, 40 | 0.0, 41 | -263.146073893067, 42 | 0.0, 43 | 618.033988749894, 44 | 0.0, 45 | 541.587312835686, 46 | 0.0, 47 | -1567.20047563694, 48 | 0.0, 49 | -866.985966358938, 50 | 0.0, 51 | -115.808021270616, 52 | 0.0, 53 | -1618.03398874989, 54 | 0.0, 55 | -613.160606150796, 56 | 0.0, 57 | 1031.37368065794, 58 | 0.0, 59 | -101.597194769693, 60 | 0.0, 61 | 450.527388478786, 62 | 0.0, 63 | 2000, 64 | 0.0, 65 | 450.527388478790, 66 | 0.0, 67 | -101.597194769691, 68 | 0.0, 69 | 1031.37368065794, 70 | 0.0, 71 | -613.160606150791, 72 | 0.0, 73 | -1618.03398874990, 74 | 0.0, 75 | -115.808021270614, 76 | 0.0, 77 | -866.985966358941, 78 | 0.0, 79 | -1567.20047563694, 80 | 0.0, 81 | 541.587312835695, 82 | 0.0, 83 | 618.033988749887, 84 | 0.0, 85 | -263.146073893066, 86 | 0.0, 87 | 1504.40995610763, 88 | 0.0, 89 | 1504.40995610762, 90 | 0.0, 91 | -263.146073893069, 92 | 0.0, 93 | 618.033988749893, 94 | 0.0, 95 | 541.587312835687, 96 | 0.0, 97 | -1567.20047563694, 98 | 0.0, 99 | -866.985966358946, 100 | 0.0, 101 | -115.808021270611, 102 | 0.0, 103 | -1618.03398874989, 104 | 0.0, 105 | -613.160606150798, 106 | 0.0, 107 | 1031.37368065794, 108 | 0.0, 109 | -101.597194769688, 110 | 0.0, 111 | 450.527388478784, 112 | 0.0, 113 | 2000, 114 | 0.0, 115 | 450.527388478792, 116 | 0.0, 117 | -101.597194769692, 118 | 0.0, 119 | 1031.37368065794, 120 | 0.0, 121 | -613.160606150806, 122 | 0.0, 123 | -1618.03398874989, 124 | 0.0, 125 | -115.808021270608, 126 | 0.0, 127 | -866.985966358952, 128 | 0.0, 129 | -1567.20047563695, 130 | 0.0, 131 | 541.587312835680, 132 | 0.0, 133 | 618.033988749898, 134 | 0.0, 135 | -263.146073893067, 136 | 0.0, 137 | 1504.40995610763, 138 | 0.0, 139 | 1504.40995610762, 140 | 0.0, 141 | -263.146073893068, 142 | 0.0, 143 | }; 144 | 145 | long startTime; 146 | long calcTime; 147 | 148 | void setup() 149 | { 150 | Serial.begin(9600); 151 | startTime = millis(); 152 | FFT(data, DATA_LEN); 153 | calcTime = millis() - startTime; 154 | Serial.print("Total calculation time: "); 155 | Serial.println(calcTime); 156 | for (int i = 0; i < DATA_LEN; i++) 157 | { 158 | Serial.println(abs(data[i].real)); 159 | } 160 | } 161 | 162 | void loop() 163 | { 164 | // put your main code here, to run repeatedly: 165 | } 166 | -------------------------------------------------------------------------------- /examples/fir/fir.ino: -------------------------------------------------------------------------------- 1 | /*This is a signal sum of 800 hz and 3.2 khz sine waves 2 | which sampled in 10khz and 32 of this samples are 3 | create a data array.(input signal) 4 | In this example input signal is filtered with 5 | 46 points fir filter. Filter is designed as low pass filter 6 | and filter coeficient calculated at Octave 7 | more info https://github.com/mozanunal/SimpleDSP/wiki/FIR 8 | */ 9 | #include "simpleDSP_fir.h" 10 | 11 | float coef[46] = 12 | { 13 | 0.00113053589111100, 14 | 0.00101072486672204, 15 | 0.000468847235288906, 16 | 0.000603489038578611, 17 | -0.00208429064928862, 18 | -0.00340892103405782, 19 | -0.00362003403497889, 20 | -0.00179251511006564, 21 | 0.00229274890344763, 22 | 0.00758093034996730, 23 | 0.0117041456801663, 24 | 0.0117198866352666, 25 | 0.00550311571071171, 26 | -0.00673606239661105, 27 | -0.0215570909070923, 28 | -0.0326442238558300, 29 | -0.0325783280789586, 30 | -0.0155583311041979, 31 | 0.0199164513221244, 32 | 0.0695391190116097, 33 | 0.123656990515743, 34 | 0.169767912370886, 35 | 0.196291877716615, 36 | 0.196291877716615, 37 | 0.169767912370886, 38 | 0.123656990515743, 39 | 0.0695391190116097, 40 | 0.0199164513221244, 41 | -0.0155583311041979, 42 | -0.0325783280789586, 43 | -0.0326442238558300, 44 | -0.0215570909070923, 45 | -0.00673606239661105, 46 | 0.00550311571071171, 47 | 0.0117198866352666, 48 | 0.0117041456801663, 49 | 0.00758093034996730, 50 | 0.00229274890344763, 51 | -0.00179251511006564, 52 | -0.00362003403497889, 53 | -0.00340892103405782, 54 | -0.00208429064928862, 55 | -0.000603489038578611, 56 | 0.000468847235288906, 57 | 0.00101072486672204, 58 | 0.00113053589111100}; 59 | 60 | int input[255] = 61 | { 62 | 450.527, 63 | -101.597, 64 | 1031.37, 65 | -613.161, 66 | -1618.03, 67 | -115.808, 68 | -866.986, 69 | -1567.2, 70 | 541.587, 71 | 618.034, 72 | -263.146, 73 | 1504.41, 74 | 1504.41, 75 | -263.146, 76 | 618.034, 77 | 541.587, 78 | -1567.2, 79 | -866.986, 80 | -115.808, 81 | -1618.03, 82 | -613.161, 83 | 1031.37, 84 | -101.597, 85 | 450.527, 86 | 2000, 87 | 450.527, 88 | -101.597, 89 | 1031.37, 90 | -613.161, 91 | -1618.03, 92 | -115.808, 93 | -866.986, 94 | -1567.2, 95 | 541.587, 96 | 618.034, 97 | -263.146, 98 | 1504.41, 99 | 1504.41, 100 | -263.146, 101 | 618.034, 102 | 541.587, 103 | -1567.2, 104 | -866.986, 105 | -115.808, 106 | -1618.03, 107 | -613.161, 108 | 1031.37, 109 | -101.597, 110 | 450.527, 111 | 2000, 112 | 450.527, 113 | -101.597, 114 | 1031.37, 115 | -613.161, 116 | -1618.03, 117 | -115.808, 118 | -866.986, 119 | -1567.2, 120 | 541.587, 121 | 618.034, 122 | -263.146, 123 | 1504.41, 124 | 1504.41, 125 | -263.146, 126 | 618.034, 127 | 541.587, 128 | -1567.2, 129 | -866.986, 130 | -115.808, 131 | -1618.03, 132 | -613.161, 133 | 1031.37, 134 | -101.597, 135 | 450.527, 136 | 2000, 137 | 450.527, 138 | -101.597, 139 | 1031.37, 140 | -613.161, 141 | -1618.03, 142 | -115.808, 143 | -866.986, 144 | -1567.2, 145 | 541.587, 146 | 618.034, 147 | -263.146, 148 | 1504.41, 149 | 1504.41, 150 | -263.146, 151 | 618.034, 152 | 541.587, 153 | -1567.2, 154 | -866.986, 155 | -115.808, 156 | -1618.03, 157 | -613.161, 158 | 1031.37, 159 | -101.597, 160 | 450.527, 161 | 2000, 162 | 450.527, 163 | -101.597, 164 | 1031.37, 165 | -613.161, 166 | -1618.03, 167 | -115.808, 168 | -866.986, 169 | -1567.2, 170 | 541.587, 171 | 618.034, 172 | -263.146, 173 | 1504.41, 174 | 1504.41, 175 | -263.146, 176 | 618.034, 177 | 541.587, 178 | -1567.2, 179 | -866.986, 180 | -115.808, 181 | -1618.03, 182 | -613.161, 183 | 1031.37, 184 | -101.597, 185 | 450.527, 186 | 2000, 187 | 450.527, 188 | -101.597, 189 | 1031.37, 190 | -613.161, 191 | -1618.03, 192 | -115.808, 193 | -866.986, 194 | -1567.2, 195 | 541.587, 196 | 618.034, 197 | -263.146, 198 | 1504.41, 199 | 1504.41, 200 | -263.146, 201 | 618.034, 202 | 541.587, 203 | -1567.2, 204 | -866.986, 205 | -115.808, 206 | -1618.03, 207 | -613.161, 208 | 1031.37, 209 | -101.597, 210 | 450.527, 211 | 2000, 212 | 450.527, 213 | -101.597, 214 | 1031.37, 215 | -613.161, 216 | -1618.03, 217 | -115.808, 218 | -866.986, 219 | -1567.2, 220 | 541.587, 221 | 618.034, 222 | -263.146, 223 | 1504.41, 224 | 1504.41, 225 | -263.146, 226 | 618.034, 227 | 541.587, 228 | -1567.2, 229 | -866.986, 230 | -115.808, 231 | -1618.03, 232 | -613.161, 233 | 1031.37, 234 | -101.597, 235 | 450.527, 236 | 2000, 237 | 450.527, 238 | -101.597, 239 | 1031.37, 240 | -613.161, 241 | -1618.03, 242 | -115.808, 243 | -866.986, 244 | -1567.2, 245 | 541.587, 246 | 618.034, 247 | -263.146, 248 | 1504.41, 249 | 1504.41, 250 | -263.146, 251 | 618.034, 252 | 541.587, 253 | -1567.2, 254 | -866.986, 255 | -115.808, 256 | -1618.03, 257 | -613.161, 258 | 1031.37, 259 | -101.597, 260 | 450.527, 261 | 2000, 262 | 450.527, 263 | -101.597, 264 | 1031.37, 265 | -613.161, 266 | -1618.03, 267 | -115.808, 268 | -866.986, 269 | -1567.2, 270 | 541.587, 271 | 618.034, 272 | -263.146, 273 | 1504.41, 274 | 1504.41, 275 | -263.146, 276 | 618.034, 277 | 541.587, 278 | -1567.2, 279 | -866.986, 280 | -115.808, 281 | -1618.03, 282 | -613.161, 283 | 1031.37, 284 | -101.597, 285 | 450.527, 286 | 2000, 287 | 450.527, 288 | -101.597, 289 | 1031.37, 290 | -613.161, 291 | -1618.03, 292 | -115.808, 293 | -866.986, 294 | -1567.2, 295 | 541.587, 296 | 618.034, 297 | -263.146, 298 | 1504.41, 299 | 1504.41, 300 | -263.146, 301 | 618.034, 302 | 541.587, 303 | -1567.2, 304 | -866.986, 305 | -115.808, 306 | -1618.03, 307 | -613.161, 308 | 1031.37, 309 | -101.597, 310 | 450.527, 311 | 2000, 312 | 450.527, 313 | -101.597, 314 | 1031.37, 315 | -613.161, 316 | -1618.03}; 317 | 318 | FIR fir1; 319 | 320 | long startTime; 321 | long calcTime; 322 | 323 | void setup() 324 | { 325 | Serial.begin(9600); 326 | firInit(&fir1, 46, coef); 327 | Serial.println("FIR filter initiliaze finished"); 328 | float a; 329 | startTime = micros(); 330 | for (int i = 0; i < 255; i++) 331 | { 332 | a = firFilt(&fir1, input[i]); 333 | } 334 | calcTime = micros() - startTime; 335 | Serial.print("Total calculation time: "); 336 | Serial.println(calcTime); 337 | } 338 | 339 | void loop() 340 | { 341 | } 342 | -------------------------------------------------------------------------------- /examples/iir/iir.ino: -------------------------------------------------------------------------------- 1 | /*This is a signal sum of 800 hz and 3.2 khz sine waves 2 | which sampled in 10khz and 32 of this samples are 3 | create a data array.(input signal) 4 | In this example input signal is filtered with 5 | 8 points iir filter. Filter is designed as low pass filter 6 | and filter coeficient calculated at Octave 7 | more info https://github.com/mozanunal/SimpleDSP/wiki/IIR 8 | */ 9 | extern "C" { 10 | #include "simpleDSP_iir.h" 11 | } 12 | 13 | float coefB[4] = 14 | { 15 | 0.049533, 16 | 0.1486, 17 | 0.1486, 18 | 0.049533}; 19 | 20 | float coefA[4] = 21 | { 22 | 1, 23 | -1.1619, 24 | 0.69594, 25 | -0.13776}; 26 | 27 | int input[255] = 28 | { 29 | 450.527, 30 | -101.597, 31 | 1031.37, 32 | -613.161, 33 | -1618.03, 34 | -115.808, 35 | -866.986, 36 | -1567.2, 37 | 541.587, 38 | 618.034, 39 | -263.146, 40 | 1504.41, 41 | 1504.41, 42 | -263.146, 43 | 618.034, 44 | 541.587, 45 | -1567.2, 46 | -866.986, 47 | -115.808, 48 | -1618.03, 49 | -613.161, 50 | 1031.37, 51 | -101.597, 52 | 450.527, 53 | 2000, 54 | 450.527, 55 | -101.597, 56 | 1031.37, 57 | -613.161, 58 | -1618.03, 59 | -115.808, 60 | -866.986, 61 | -1567.2, 62 | 541.587, 63 | 618.034, 64 | -263.146, 65 | 1504.41, 66 | 1504.41, 67 | -263.146, 68 | 618.034, 69 | 541.587, 70 | -1567.2, 71 | -866.986, 72 | -115.808, 73 | -1618.03, 74 | -613.161, 75 | 1031.37, 76 | -101.597, 77 | 450.527, 78 | 2000, 79 | 450.527, 80 | -101.597, 81 | 1031.37, 82 | -613.161, 83 | -1618.03, 84 | -115.808, 85 | -866.986, 86 | -1567.2, 87 | 541.587, 88 | 618.034, 89 | -263.146, 90 | 1504.41, 91 | 1504.41, 92 | -263.146, 93 | 618.034, 94 | 541.587, 95 | -1567.2, 96 | -866.986, 97 | -115.808, 98 | -1618.03, 99 | -613.161, 100 | 1031.37, 101 | -101.597, 102 | 450.527, 103 | 2000, 104 | 450.527, 105 | -101.597, 106 | 1031.37, 107 | -613.161, 108 | -1618.03, 109 | -115.808, 110 | -866.986, 111 | -1567.2, 112 | 541.587, 113 | 618.034, 114 | -263.146, 115 | 1504.41, 116 | 1504.41, 117 | -263.146, 118 | 618.034, 119 | 541.587, 120 | -1567.2, 121 | -866.986, 122 | -115.808, 123 | -1618.03, 124 | -613.161, 125 | 1031.37, 126 | -101.597, 127 | 450.527, 128 | 2000, 129 | 450.527, 130 | -101.597, 131 | 1031.37, 132 | -613.161, 133 | -1618.03, 134 | -115.808, 135 | -866.986, 136 | -1567.2, 137 | 541.587, 138 | 618.034, 139 | -263.146, 140 | 1504.41, 141 | 1504.41, 142 | -263.146, 143 | 618.034, 144 | 541.587, 145 | -1567.2, 146 | -866.986, 147 | -115.808, 148 | -1618.03, 149 | -613.161, 150 | 1031.37, 151 | -101.597, 152 | 450.527, 153 | 2000, 154 | 450.527, 155 | -101.597, 156 | 1031.37, 157 | -613.161, 158 | -1618.03, 159 | -115.808, 160 | -866.986, 161 | -1567.2, 162 | 541.587, 163 | 618.034, 164 | -263.146, 165 | 1504.41, 166 | 1504.41, 167 | -263.146, 168 | 618.034, 169 | 541.587, 170 | -1567.2, 171 | -866.986, 172 | -115.808, 173 | -1618.03, 174 | -613.161, 175 | 1031.37, 176 | -101.597, 177 | 450.527, 178 | 2000, 179 | 450.527, 180 | -101.597, 181 | 1031.37, 182 | -613.161, 183 | -1618.03, 184 | -115.808, 185 | -866.986, 186 | -1567.2, 187 | 541.587, 188 | 618.034, 189 | -263.146, 190 | 1504.41, 191 | 1504.41, 192 | -263.146, 193 | 618.034, 194 | 541.587, 195 | -1567.2, 196 | -866.986, 197 | -115.808, 198 | -1618.03, 199 | -613.161, 200 | 1031.37, 201 | -101.597, 202 | 450.527, 203 | 2000, 204 | 450.527, 205 | -101.597, 206 | 1031.37, 207 | -613.161, 208 | -1618.03, 209 | -115.808, 210 | -866.986, 211 | -1567.2, 212 | 541.587, 213 | 618.034, 214 | -263.146, 215 | 1504.41, 216 | 1504.41, 217 | -263.146, 218 | 618.034, 219 | 541.587, 220 | -1567.2, 221 | -866.986, 222 | -115.808, 223 | -1618.03, 224 | -613.161, 225 | 1031.37, 226 | -101.597, 227 | 450.527, 228 | 2000, 229 | 450.527, 230 | -101.597, 231 | 1031.37, 232 | -613.161, 233 | -1618.03, 234 | -115.808, 235 | -866.986, 236 | -1567.2, 237 | 541.587, 238 | 618.034, 239 | -263.146, 240 | 1504.41, 241 | 1504.41, 242 | -263.146, 243 | 618.034, 244 | 541.587, 245 | -1567.2, 246 | -866.986, 247 | -115.808, 248 | -1618.03, 249 | -613.161, 250 | 1031.37, 251 | -101.597, 252 | 450.527, 253 | 2000, 254 | 450.527, 255 | -101.597, 256 | 1031.37, 257 | -613.161, 258 | -1618.03, 259 | -115.808, 260 | -866.986, 261 | -1567.2, 262 | 541.587, 263 | 618.034, 264 | -263.146, 265 | 1504.41, 266 | 1504.41, 267 | -263.146, 268 | 618.034, 269 | 541.587, 270 | -1567.2, 271 | -866.986, 272 | -115.808, 273 | -1618.03, 274 | -613.161, 275 | 1031.37, 276 | -101.597, 277 | 450.527, 278 | 2000, 279 | 450.527, 280 | -101.597, 281 | 1031.37, 282 | -613.161, 283 | -1618.03}; 284 | 285 | IIR iir1; 286 | 287 | long startTime; 288 | long calcTime; 289 | 290 | void setup() 291 | { 292 | Serial.begin(9600); 293 | iirInit(&iir1, 4, coefB, 4, coefA); 294 | Serial.println("IIR filter initiliaze finished"); 295 | float a; 296 | startTime = micros(); 297 | for (int i = 0; i < 255; i++) 298 | { 299 | a = iirFilt(&iir1, input[i]); 300 | } 301 | calcTime = micros() - startTime; 302 | Serial.print("Total calculation time: "); 303 | Serial.println(calcTime); 304 | } 305 | 306 | void loop() 307 | { 308 | } 309 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ########################################### 2 | # Syntax Coloring Map For SimpleDSP 3 | ########################################### 4 | 5 | ########################################### 6 | # Datatypes (KEYWORD1) 7 | ########################################### 8 | 9 | COMPLEX KEYWORD1 10 | FIR KEYWORD1 11 | IIR KEYWORD1 12 | 13 | ########################################### 14 | # Methods and Functions (KEYWORD2) 15 | ########################################### 16 | 17 | FFT KEYWORD2 18 | IFFT KEYWORD2 19 | 20 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=SimpleDSP 2 | version=1.0.0 3 | author=Mehmet Ozan Unal 4 | maintainer=Mehmet Ozan Unal 5 | sentence=SimpleDSP library for embedded systems 6 | paragraph=FFT IFFT 7 | category=Sensors 8 | url=https://github.com/mozanunal/SimpleDSP 9 | architectures=* 10 | -------------------------------------------------------------------------------- /simpleDSP_Global.h: -------------------------------------------------------------------------------- 1 | /* begin simpleDSP_Global.h */ 2 | #ifndef _SIMPLEDSP_GLOBAL_H 3 | #define _SIMPLEDSP_GLOBAL_H 4 | 5 | typedef struct 6 | { 7 | float real; 8 | float imag; 9 | } COMPLEX; 10 | 11 | #endif /* end simpleDSP_Global.h */ 12 | -------------------------------------------------------------------------------- /simpleDSP_fft.c: -------------------------------------------------------------------------------- 1 | /* 2 | N point Complex fft and inverse fft functions 3 | */ 4 | 5 | #include "simpleDSP_fft.h" 6 | 7 | COMPLEX w[] = { 8 | 1.00000, -0.00000, 9 | 0.99970, -0.02454, 10 | 0.99880, -0.04907, 11 | 0.99729, -0.07356, 12 | 0.99518, -0.09802, 13 | 0.99248, -0.12241, 14 | 0.98918, -0.14673, 15 | 0.98528, -0.17096, 16 | 0.98079, -0.19509, 17 | 0.97570, -0.21910, 18 | 0.97003, -0.24298, 19 | 0.96378, -0.26671, 20 | 0.95694, -0.29028, 21 | 0.94953, -0.31368, 22 | 0.94154, -0.33689, 23 | 0.93299, -0.35990, 24 | 0.92388, -0.38268, 25 | 0.91421, -0.40524, 26 | 0.90399, -0.42756, 27 | 0.89322, -0.44961, 28 | 0.88192, -0.47140, 29 | 0.87009, -0.49290, 30 | 0.85773, -0.51410, 31 | 0.84485, -0.53500, 32 | 0.83147, -0.55557, 33 | 0.81758, -0.57581, 34 | 0.80321, -0.59570, 35 | 0.78835, -0.61523, 36 | 0.77301, -0.63439, 37 | 0.75721, -0.65317, 38 | 0.74095, -0.67156, 39 | 0.72425, -0.68954, 40 | 0.70711, -0.70711, 41 | 0.68954, -0.72425, 42 | 0.67156, -0.74095, 43 | 0.65317, -0.75721, 44 | 0.63439, -0.77301, 45 | 0.61523, -0.78835, 46 | 0.59570, -0.80321, 47 | 0.57581, -0.81758, 48 | 0.55557, -0.83147, 49 | 0.53500, -0.84485, 50 | 0.51410, -0.85773, 51 | 0.49290, -0.87009, 52 | 0.47140, -0.88192, 53 | 0.44961, -0.89322, 54 | 0.42756, -0.90399, 55 | 0.40524, -0.91421, 56 | 0.38268, -0.92388, 57 | 0.35990, -0.93299, 58 | 0.33689, -0.94154, 59 | 0.31368, -0.94953, 60 | 0.29028, -0.95694, 61 | 0.26671, -0.96378, 62 | 0.24298, -0.97003, 63 | 0.21910, -0.97570, 64 | 0.19509, -0.98079, 65 | 0.17096, -0.98528, 66 | 0.14673, -0.98918, 67 | 0.12241, -0.99248, 68 | 0.09802, -0.99518, 69 | 0.07356, -0.99729, 70 | 0.04907, -0.99880, 71 | 0.02454, -0.99970, 72 | -0.00000, -1.00000, 73 | -0.02454, -0.99970, 74 | -0.04907, -0.99880, 75 | -0.07356, -0.99729, 76 | -0.09802, -0.99518, 77 | -0.12241, -0.99248, 78 | -0.14673, -0.98918, 79 | -0.17096, -0.98528, 80 | -0.19509, -0.98079, 81 | -0.21910, -0.97570, 82 | -0.24298, -0.97003, 83 | -0.26671, -0.96378, 84 | -0.29028, -0.95694, 85 | -0.31368, -0.94953, 86 | -0.33689, -0.94154, 87 | -0.35990, -0.93299, 88 | -0.38268, -0.92388, 89 | -0.40524, -0.91421, 90 | -0.42756, -0.90399, 91 | -0.44961, -0.89322, 92 | -0.47140, -0.88192, 93 | -0.49290, -0.87009, 94 | -0.51410, -0.85773, 95 | -0.53500, -0.84485, 96 | -0.55557, -0.83147, 97 | -0.57581, -0.81758, 98 | -0.59570, -0.80321, 99 | -0.61523, -0.78835, 100 | -0.63439, -0.77301, 101 | -0.65317, -0.75721, 102 | -0.67156, -0.74095, 103 | -0.68954, -0.72425, 104 | -0.70711, -0.70711, 105 | -0.72425, -0.68954, 106 | -0.74095, -0.67156, 107 | -0.75721, -0.65317, 108 | -0.77301, -0.63439, 109 | -0.78835, -0.61523, 110 | -0.80321, -0.59570, 111 | -0.81758, -0.57581, 112 | -0.83147, -0.55557, 113 | -0.84485, -0.53500, 114 | -0.85773, -0.51410, 115 | -0.87009, -0.49290, 116 | -0.88192, -0.47140, 117 | -0.89322, -0.44961, 118 | -0.90399, -0.42756, 119 | -0.91421, -0.40524, 120 | -0.92388, -0.38268, 121 | -0.93299, -0.35990, 122 | -0.94154, -0.33689, 123 | -0.94953, -0.31368, 124 | -0.95694, -0.29028, 125 | -0.96378, -0.26671, 126 | -0.97003, -0.24298, 127 | -0.97570, -0.21910, 128 | -0.98079, -0.19509, 129 | -0.98528, -0.17096, 130 | -0.98918, -0.14673, 131 | -0.99248, -0.12241, 132 | -0.99518, -0.09802, 133 | -0.99729, -0.07356, 134 | -0.99880, -0.04907, 135 | -0.99970, -0.02454}; 136 | 137 | void FFT(COMPLEX *Y, int N) /*input sample array, # of points */ 138 | { 139 | COMPLEX temp1, temp2; /*temporary storage variables */ 140 | int i, j, k; /*loop counter variables */ 141 | int upper_leg, lower_leg; /*index of upper/lower butterfly leg */ 142 | int leg_diff; /*difference between upper/lower leg */ 143 | int num_stages = 0; /*number of FFT stages, or iterations */ 144 | int index, step; /*index and step between twiddle factor*/ 145 | 146 | /* log(base 2) of # of points = # of stages */ 147 | i = 1; 148 | do 149 | { 150 | num_stages += 1; 151 | i = i * 2; 152 | } while (i != N); 153 | 154 | /* starting difference between upper and lower butterfly legs*/ 155 | leg_diff = N / 2; 156 | /* step between values in twiddle factor array twiddle.h */ 157 | step = 256 / N; 158 | /* For N-point FFT */ 159 | 160 | for (i = 0; i < num_stages; i++) 161 | { 162 | index = 0; 163 | for (j = 0; j < leg_diff; j++) 164 | { 165 | for (upper_leg = j; upper_leg < N; upper_leg += (2 * leg_diff)) 166 | { 167 | lower_leg = upper_leg + leg_diff; 168 | temp1.real = (Y[upper_leg]).real + (Y[lower_leg]).real; 169 | temp1.imag = (Y[upper_leg]).imag + (Y[lower_leg]).imag; 170 | temp2.real = (Y[upper_leg]).real - (Y[lower_leg]).real; 171 | temp2.imag = (Y[upper_leg]).imag - (Y[lower_leg]).imag; 172 | (Y[lower_leg]).real = temp2.real * (w[index]).real - temp2.imag * (w[index]).imag; 173 | (Y[lower_leg]).imag = temp2.real * (w[index]).imag + temp2.imag * (w[index]).real; 174 | (Y[upper_leg]).real = temp1.real; 175 | (Y[upper_leg]).imag = temp1.imag; 176 | } 177 | index += step; 178 | } 179 | leg_diff = leg_diff / 2; 180 | step *= 2; 181 | } 182 | /* bit reversal for resequencing data */ 183 | j = 0; 184 | for (i = 1; i < (N - 1); i++) 185 | { 186 | k = N / 2; 187 | while (k <= j) 188 | { 189 | j = j - k; 190 | k = k / 2; 191 | } 192 | j = j + k; 193 | if (i < j) 194 | { 195 | temp1.real = (Y[j]).real; 196 | temp1.imag = (Y[j]).imag; 197 | (Y[j]).real = (Y[i]).real; 198 | (Y[j]).imag = (Y[i]).imag; 199 | (Y[i]).real = temp1.real; 200 | (Y[i]).imag = temp1.imag; 201 | } 202 | } 203 | return; 204 | } 205 | 206 | void IFFT(COMPLEX *Y, int N) /*input sample array, # of points */ 207 | { 208 | COMPLEX temp1, temp2; /*temporary storage variables */ 209 | int i, j, k; /*loop counter variables */ 210 | int upper_leg, lower_leg; /*index of upper/lower butterfly leg */ 211 | int leg_diff; /*difference between upper/lower leg */ 212 | int num_stages = 0; /*number of FFT stages, or iterations */ 213 | int index, step; /*index and step between twiddle factor*/ 214 | 215 | for (i = 0; i <= 127; i++) 216 | { 217 | w[i].real = w[i].real; 218 | w[i].imag = -w[i].imag; 219 | } 220 | 221 | /* log(base 2) of # of points = # of stages */ 222 | i = 1; 223 | do 224 | { 225 | num_stages += 1; 226 | i = i * 2; 227 | } while (i != N); 228 | 229 | /* starting difference between upper and lower butterfly legs*/ 230 | leg_diff = N / 2; 231 | /* step between values in twiddle factor array twiddle.h */ 232 | step = 256 / N; 233 | /* For N-point FFT */ 234 | 235 | for (i = 0; i < num_stages; i++) 236 | { 237 | index = 0; 238 | for (j = 0; j < leg_diff; j++) 239 | { 240 | for (upper_leg = j; upper_leg < N; upper_leg += (2 * leg_diff)) 241 | { 242 | lower_leg = upper_leg + leg_diff; 243 | temp1.real = (Y[upper_leg]).real + (Y[lower_leg]).real; 244 | temp1.imag = (Y[upper_leg]).imag + (Y[lower_leg]).imag; 245 | temp2.real = (Y[upper_leg]).real - (Y[lower_leg]).real; 246 | temp2.imag = (Y[upper_leg]).imag - (Y[lower_leg]).imag; 247 | (Y[lower_leg]).real = temp2.real * (w[index]).real - temp2.imag * (w[index]).imag; 248 | (Y[lower_leg]).imag = temp2.real * (w[index]).imag + temp2.imag * (w[index]).real; 249 | (Y[upper_leg]).real = temp1.real; 250 | (Y[upper_leg]).imag = temp1.imag; 251 | } 252 | index += step; 253 | } 254 | leg_diff = leg_diff / 2; 255 | step *= 2; 256 | } 257 | /* bit reversal for resequencing data */ 258 | j = 0; 259 | for (i = 1; i < (N - 1); i++) 260 | { 261 | k = N / 2; 262 | while (k <= j) 263 | { 264 | j = j - k; 265 | k = k / 2; 266 | } 267 | j = j + k; 268 | if (i < j) 269 | { 270 | temp1.real = (Y[j]).real; 271 | temp1.imag = (Y[j]).imag; 272 | (Y[j]).real = (Y[i]).real; 273 | (Y[j]).imag = (Y[i]).imag; 274 | (Y[i]).real = temp1.real; 275 | (Y[i]).imag = temp1.imag; 276 | } 277 | } 278 | return; 279 | } 280 | -------------------------------------------------------------------------------- /simpleDSP_fft.h: -------------------------------------------------------------------------------- 1 | /* begin simpleDSP_fft.h */ 2 | #ifndef _SIMPLEDSP_FFT_H 3 | #define _SIMPLEDSP_FFT_H 4 | 5 | #include "simpleDSP_Global.h" 6 | 7 | void FFT(COMPLEX *Y, int N); 8 | void IFFT(COMPLEX *Y, int N); 9 | 10 | #endif /* end simpleDSP_fft.h */ 11 | -------------------------------------------------------------------------------- /simpleDSP_fir.c: -------------------------------------------------------------------------------- 1 | 2 | #include "simpleDSP_fir.h" 3 | 4 | void firInit(FIR *fir, int coefBLen, float *coefsB) 5 | { 6 | fir->coefBLen = coefBLen; 7 | fir->coefsB = (float *)malloc(fir->coefBLen * 4); 8 | fir->dlyX = (float *)malloc(fir->coefBLen * 4); 9 | for (int i = 0; i < fir->coefBLen; i++) 10 | fir->dlyX[i] = 0.0; 11 | fir->coefsB = coefsB; 12 | } 13 | 14 | float firFilt(FIR *fir, int input) 15 | { 16 | float acc = 0.0; 17 | fir->dlyX[0] = input; 18 | for (int i = 0; i < fir->coefBLen; i++) 19 | acc += fir->coefsB[i] * fir->dlyX[i]; 20 | for (int i = (fir->coefBLen) - 1; i > 0; i--) 21 | fir->dlyX[i] = fir->dlyX[i - 1]; 22 | return acc; 23 | } 24 | -------------------------------------------------------------------------------- /simpleDSP_fir.h: -------------------------------------------------------------------------------- 1 | /* begin simpleDSP_fir.h */ 2 | #ifndef _SIMPLEDSP_FIR_H 3 | #define _SIMPLEDSP_FIR_H 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #include "simpleDSP_Global.h" 10 | #include 11 | #include 12 | 13 | typedef struct 14 | { 15 | int coefBLen; 16 | float *coefsB; 17 | float *dlyX; 18 | }FIR; 19 | 20 | void firInit(FIR *fir, int coefBLen, float *coefsB); 21 | float firFilt(FIR *fir, int input); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | 27 | #endif /*end simpleDSP_fir.h */ 28 | -------------------------------------------------------------------------------- /simpleDSP_iir.c: -------------------------------------------------------------------------------- 1 | 2 | #include "simpleDSP_iir.h" 3 | 4 | void iirInit(IIR *iir, int coefBLen, float *coefsB, int coefALen, float *coefsA) 5 | { 6 | /* memory allocation for H and delay values */ 7 | iir->coefsB = (float *)malloc(iir->coefBLen * 4); 8 | iir->coefsA = (float *)malloc(iir->coefALen * 4); 9 | iir->dlyX = (float *)malloc(iir->coefBLen * 4); 10 | iir->dlyY = (float *)malloc(iir->coefALen * 4); 11 | /* init parameters */ 12 | iir->coefBLen = coefBLen; 13 | iir->coefALen = coefALen; 14 | iir->coefsB = coefsB; 15 | iir->coefsA = coefsA; 16 | for (int i = 0; i < iir->coefBLen; i++) 17 | iir->dlyX[i] = 0.0; 18 | for (int i = 0; i < iir->coefALen; i++) 19 | iir->dlyY[i] = 0.0; 20 | } 21 | 22 | float iirFilt(IIR *iir, int input) 23 | { 24 | // xn[6]=xn[5] 25 | // xn[5]=xn[4] 26 | // xn[4]=xn[3] 27 | // xn[3]=xn[2] 28 | // xn[2]=xn[1] 29 | // xn[1]=xn[0] 30 | // xn[0]= giris 31 | 32 | // yn[6]=yn[5] 33 | // yn[5]=yn[4] 34 | // yn[4]=yn[3] 35 | // yn[3]=yn[2] 36 | // yn[2]=yn[1] 37 | // yn[1]=cikis 38 | // m1 = b2[0]*giris+b2[1]*xn[1]+b2[2]*xn[2]+b2[3]*xn[3]+b2[4]*xn[4]+b2[5]*xn[5]+b2[6]*xn[6] 39 | // m2 = -a2[1]*yn[1]-a2[2]*yn[2]-a2[3]*yn[3]-a2[4]*yn[4]-a2[5]*yn[5]-a2[6]*yn[6] 40 | // cikis = m1 + m2 41 | // #print m1,m2 42 | // return cikis 43 | float acc1 = 0.0; 44 | float acc2 = 0.0; 45 | /* b coeficients*/ 46 | iir->dlyX[0] = input; 47 | for (int i = 0; i < iir->coefBLen; i++) 48 | acc1 += iir->coefsB[i] * iir->dlyX[i]; 49 | for (int i = (iir->coefBLen) - 1; i > 0; i--) 50 | iir->dlyX[i] = iir->dlyX[i - 1]; 51 | /* a coeficients*/ 52 | iir->dlyY[0] = 0; 53 | for (int i = 0; i < iir->coefALen; i++) 54 | acc1 += iir->coefsA[i] * iir->dlyY[i]; 55 | for (int i = (iir->coefALen) - 1; i > 0; i--) 56 | iir->dlyY[i] = iir->dlyY[i - 1]; 57 | return acc1+acc2; 58 | } 59 | -------------------------------------------------------------------------------- /simpleDSP_iir.h: -------------------------------------------------------------------------------- 1 | /* begin simpleDSP_iir.h */ 2 | #ifndef _SIMPLEDSP_IIR_H 3 | #define _SIMPLEDSP_IIR_H 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #include "simpleDSP_Global.h" 10 | #include 11 | #include 12 | 13 | 14 | typedef struct 15 | { 16 | int coefALen; 17 | float *coefsA; 18 | int coefBLen; 19 | float *coefsB; 20 | float *dlyX; 21 | float *dlyY; 22 | }IIR; 23 | 24 | void iirInit(IIR *iir, int coefBLen, float *coefsB, int coefALen, float *coefsA); 25 | float iirFilt(IIR *iir, int input); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif /* end simpleDSP_iir.h */ 32 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | ######################################################## 2 | # SimpleDSP # 3 | # # 4 | # # 5 | # # 6 | # # 7 | ######################################################## 8 | CC = gcc 9 | INCLUDE = 10 | 11 | SRC = testIIR.c simpleDSP_iir.c 12 | 13 | OUT = testFIR 14 | CCFLAGS = 15 | LDFLAGS = 16 | 17 | all: build 18 | 19 | build: $(SRC) 20 | @echo Compiling $(basename $<)... 21 | $(CC) $(CCFLAGS) $(INCLUDE) $(SRC) -o $(OUT) $(LDFLAGS) 22 | 23 | run: 24 | ./$(OUT) 25 | 26 | clean: 27 | rm -rf *.dSYM -------------------------------------------------------------------------------- /test/testFIR.c: -------------------------------------------------------------------------------- 1 | 2 | #include "simpleDSP_fir.h" 3 | #include 4 | 5 | float coef[46] = 6 | { 7 | 0.00113053589111100, 8 | 0.00101072486672204, 9 | 0.000468847235288906, 10 | 0.000603489038578611, 11 | -0.00208429064928862, 12 | -0.00340892103405782, 13 | -0.00362003403497889, 14 | -0.00179251511006564, 15 | 0.00229274890344763, 16 | 0.00758093034996730, 17 | 0.0117041456801663, 18 | 0.0117198866352666, 19 | 0.00550311571071171, 20 | -0.00673606239661105, 21 | -0.0215570909070923, 22 | -0.0326442238558300, 23 | -0.0325783280789586, 24 | -0.0155583311041979, 25 | 0.0199164513221244, 26 | 0.0695391190116097, 27 | 0.123656990515743, 28 | 0.169767912370886, 29 | 0.196291877716615, 30 | 0.196291877716615, 31 | 0.169767912370886, 32 | 0.123656990515743, 33 | 0.0695391190116097, 34 | 0.0199164513221244, 35 | -0.0155583311041979, 36 | -0.0325783280789586, 37 | -0.0326442238558300, 38 | -0.0215570909070923, 39 | -0.00673606239661105, 40 | 0.00550311571071171, 41 | 0.0117198866352666, 42 | 0.0117041456801663, 43 | 0.00758093034996730, 44 | 0.00229274890344763, 45 | -0.00179251511006564, 46 | -0.00362003403497889, 47 | -0.00340892103405782, 48 | -0.00208429064928862, 49 | -0.000603489038578611, 50 | 0.000468847235288906, 51 | 0.00101072486672204, 52 | 0.00113053589111100}; 53 | 54 | int input[255] = 55 | { 56 | 450.527, 57 | -101.597, 58 | 1031.37, 59 | -613.161, 60 | -1618.03, 61 | -115.808, 62 | -866.986, 63 | -1567.2, 64 | 541.587, 65 | 618.034, 66 | -263.146, 67 | 1504.41, 68 | 1504.41, 69 | -263.146, 70 | 618.034, 71 | 541.587, 72 | -1567.2, 73 | -866.986, 74 | -115.808, 75 | -1618.03, 76 | -613.161, 77 | 1031.37, 78 | -101.597, 79 | 450.527, 80 | 2000, 81 | 450.527, 82 | -101.597, 83 | 1031.37, 84 | -613.161, 85 | -1618.03, 86 | -115.808, 87 | -866.986, 88 | -1567.2, 89 | 541.587, 90 | 618.034, 91 | -263.146, 92 | 1504.41, 93 | 1504.41, 94 | -263.146, 95 | 618.034, 96 | 541.587, 97 | -1567.2, 98 | -866.986, 99 | -115.808, 100 | -1618.03, 101 | -613.161, 102 | 1031.37, 103 | -101.597, 104 | 450.527, 105 | 2000, 106 | 450.527, 107 | -101.597, 108 | 1031.37, 109 | -613.161, 110 | -1618.03, 111 | -115.808, 112 | -866.986, 113 | -1567.2, 114 | 541.587, 115 | 618.034, 116 | -263.146, 117 | 1504.41, 118 | 1504.41, 119 | -263.146, 120 | 618.034, 121 | 541.587, 122 | -1567.2, 123 | -866.986, 124 | -115.808, 125 | -1618.03, 126 | -613.161, 127 | 1031.37, 128 | -101.597, 129 | 450.527, 130 | 2000, 131 | 450.527, 132 | -101.597, 133 | 1031.37, 134 | -613.161, 135 | -1618.03, 136 | -115.808, 137 | -866.986, 138 | -1567.2, 139 | 541.587, 140 | 618.034, 141 | -263.146, 142 | 1504.41, 143 | 1504.41, 144 | -263.146, 145 | 618.034, 146 | 541.587, 147 | -1567.2, 148 | -866.986, 149 | -115.808, 150 | -1618.03, 151 | -613.161, 152 | 1031.37, 153 | -101.597, 154 | 450.527, 155 | 2000, 156 | 450.527, 157 | -101.597, 158 | 1031.37, 159 | -613.161, 160 | -1618.03, 161 | -115.808, 162 | -866.986, 163 | -1567.2, 164 | 541.587, 165 | 618.034, 166 | -263.146, 167 | 1504.41, 168 | 1504.41, 169 | -263.146, 170 | 618.034, 171 | 541.587, 172 | -1567.2, 173 | -866.986, 174 | -115.808, 175 | -1618.03, 176 | -613.161, 177 | 1031.37, 178 | -101.597, 179 | 450.527, 180 | 2000, 181 | 450.527, 182 | -101.597, 183 | 1031.37, 184 | -613.161, 185 | -1618.03, 186 | -115.808, 187 | -866.986, 188 | -1567.2, 189 | 541.587, 190 | 618.034, 191 | -263.146, 192 | 1504.41, 193 | 1504.41, 194 | -263.146, 195 | 618.034, 196 | 541.587, 197 | -1567.2, 198 | -866.986, 199 | -115.808, 200 | -1618.03, 201 | -613.161, 202 | 1031.37, 203 | -101.597, 204 | 450.527, 205 | 2000, 206 | 450.527, 207 | -101.597, 208 | 1031.37, 209 | -613.161, 210 | -1618.03, 211 | -115.808, 212 | -866.986, 213 | -1567.2, 214 | 541.587, 215 | 618.034, 216 | -263.146, 217 | 1504.41, 218 | 1504.41, 219 | -263.146, 220 | 618.034, 221 | 541.587, 222 | -1567.2, 223 | -866.986, 224 | -115.808, 225 | -1618.03, 226 | -613.161, 227 | 1031.37, 228 | -101.597, 229 | 450.527, 230 | 2000, 231 | 450.527, 232 | -101.597, 233 | 1031.37, 234 | -613.161, 235 | -1618.03, 236 | -115.808, 237 | -866.986, 238 | -1567.2, 239 | 541.587, 240 | 618.034, 241 | -263.146, 242 | 1504.41, 243 | 1504.41, 244 | -263.146, 245 | 618.034, 246 | 541.587, 247 | -1567.2, 248 | -866.986, 249 | -115.808, 250 | -1618.03, 251 | -613.161, 252 | 1031.37, 253 | -101.597, 254 | 450.527, 255 | 2000, 256 | 450.527, 257 | -101.597, 258 | 1031.37, 259 | -613.161, 260 | -1618.03, 261 | -115.808, 262 | -866.986, 263 | -1567.2, 264 | 541.587, 265 | 618.034, 266 | -263.146, 267 | 1504.41, 268 | 1504.41, 269 | -263.146, 270 | 618.034, 271 | 541.587, 272 | -1567.2, 273 | -866.986, 274 | -115.808, 275 | -1618.03, 276 | -613.161, 277 | 1031.37, 278 | -101.597, 279 | 450.527, 280 | 2000, 281 | 450.527, 282 | -101.597, 283 | 1031.37, 284 | -613.161, 285 | -1618.03, 286 | -115.808, 287 | -866.986, 288 | -1567.2, 289 | 541.587, 290 | 618.034, 291 | -263.146, 292 | 1504.41, 293 | 1504.41, 294 | -263.146, 295 | 618.034, 296 | 541.587, 297 | -1567.2, 298 | -866.986, 299 | -115.808, 300 | -1618.03, 301 | -613.161, 302 | 1031.37, 303 | -101.597, 304 | 450.527, 305 | 2000, 306 | 450.527, 307 | -101.597, 308 | 1031.37, 309 | -613.161, 310 | -1618.03}; 311 | 312 | FIR fir1; 313 | 314 | int main() 315 | { 316 | init(&fir1, 46, coef); 317 | printf("init finished\n"); 318 | fflush(stdout); 319 | /* 320 | for (int i = 0; i < 46; i++) { 321 | printf("\ninit %f- %d\n",fir1.H[i],fir1.n); 322 | fflush(stdout); 323 | } 324 | */ 325 | 326 | for (int i = 0; i < 255; i++) 327 | { 328 | float a; 329 | a = filt(&fir1, input[i]); 330 | printf("%f\n", a); 331 | fflush(stdout); 332 | } 333 | 334 | printf("filter finished\n"); 335 | fflush(stdout); 336 | return 0; 337 | } 338 | -------------------------------------------------------------------------------- /test/testIIR.c: -------------------------------------------------------------------------------- 1 | 2 | #include "simpleDSP_iir.h" 3 | #include 4 | 5 | float coefB[4] = 6 | { 7 | 0.049533, 8 | 0.1486, 9 | 0.1486, 10 | 0.049533}; 11 | 12 | float coefA[4] = 13 | { 14 | 1, 15 | -1.1619, 16 | 0.69594, 17 | -0.13776}; 18 | 19 | int input[255] = 20 | { 21 | 450.527, 22 | -101.597, 23 | 1031.37, 24 | -613.161, 25 | -1618.03, 26 | -115.808, 27 | -866.986, 28 | -1567.2, 29 | 541.587, 30 | 618.034, 31 | -263.146, 32 | 1504.41, 33 | 1504.41, 34 | -263.146, 35 | 618.034, 36 | 541.587, 37 | -1567.2, 38 | -866.986, 39 | -115.808, 40 | -1618.03, 41 | -613.161, 42 | 1031.37, 43 | -101.597, 44 | 450.527, 45 | 2000, 46 | 450.527, 47 | -101.597, 48 | 1031.37, 49 | -613.161, 50 | -1618.03, 51 | -115.808, 52 | -866.986, 53 | -1567.2, 54 | 541.587, 55 | 618.034, 56 | -263.146, 57 | 1504.41, 58 | 1504.41, 59 | -263.146, 60 | 618.034, 61 | 541.587, 62 | -1567.2, 63 | -866.986, 64 | -115.808, 65 | -1618.03, 66 | -613.161, 67 | 1031.37, 68 | -101.597, 69 | 450.527, 70 | 2000, 71 | 450.527, 72 | -101.597, 73 | 1031.37, 74 | -613.161, 75 | -1618.03, 76 | -115.808, 77 | -866.986, 78 | -1567.2, 79 | 541.587, 80 | 618.034, 81 | -263.146, 82 | 1504.41, 83 | 1504.41, 84 | -263.146, 85 | 618.034, 86 | 541.587, 87 | -1567.2, 88 | -866.986, 89 | -115.808, 90 | -1618.03, 91 | -613.161, 92 | 1031.37, 93 | -101.597, 94 | 450.527, 95 | 2000, 96 | 450.527, 97 | -101.597, 98 | 1031.37, 99 | -613.161, 100 | -1618.03, 101 | -115.808, 102 | -866.986, 103 | -1567.2, 104 | 541.587, 105 | 618.034, 106 | -263.146, 107 | 1504.41, 108 | 1504.41, 109 | -263.146, 110 | 618.034, 111 | 541.587, 112 | -1567.2, 113 | -866.986, 114 | -115.808, 115 | -1618.03, 116 | -613.161, 117 | 1031.37, 118 | -101.597, 119 | 450.527, 120 | 2000, 121 | 450.527, 122 | -101.597, 123 | 1031.37, 124 | -613.161, 125 | -1618.03, 126 | -115.808, 127 | -866.986, 128 | -1567.2, 129 | 541.587, 130 | 618.034, 131 | -263.146, 132 | 1504.41, 133 | 1504.41, 134 | -263.146, 135 | 618.034, 136 | 541.587, 137 | -1567.2, 138 | -866.986, 139 | -115.808, 140 | -1618.03, 141 | -613.161, 142 | 1031.37, 143 | -101.597, 144 | 450.527, 145 | 2000, 146 | 450.527, 147 | -101.597, 148 | 1031.37, 149 | -613.161, 150 | -1618.03, 151 | -115.808, 152 | -866.986, 153 | -1567.2, 154 | 541.587, 155 | 618.034, 156 | -263.146, 157 | 1504.41, 158 | 1504.41, 159 | -263.146, 160 | 618.034, 161 | 541.587, 162 | -1567.2, 163 | -866.986, 164 | -115.808, 165 | -1618.03, 166 | -613.161, 167 | 1031.37, 168 | -101.597, 169 | 450.527, 170 | 2000, 171 | 450.527, 172 | -101.597, 173 | 1031.37, 174 | -613.161, 175 | -1618.03, 176 | -115.808, 177 | -866.986, 178 | -1567.2, 179 | 541.587, 180 | 618.034, 181 | -263.146, 182 | 1504.41, 183 | 1504.41, 184 | -263.146, 185 | 618.034, 186 | 541.587, 187 | -1567.2, 188 | -866.986, 189 | -115.808, 190 | -1618.03, 191 | -613.161, 192 | 1031.37, 193 | -101.597, 194 | 450.527, 195 | 2000, 196 | 450.527, 197 | -101.597, 198 | 1031.37, 199 | -613.161, 200 | -1618.03, 201 | -115.808, 202 | -866.986, 203 | -1567.2, 204 | 541.587, 205 | 618.034, 206 | -263.146, 207 | 1504.41, 208 | 1504.41, 209 | -263.146, 210 | 618.034, 211 | 541.587, 212 | -1567.2, 213 | -866.986, 214 | -115.808, 215 | -1618.03, 216 | -613.161, 217 | 1031.37, 218 | -101.597, 219 | 450.527, 220 | 2000, 221 | 450.527, 222 | -101.597, 223 | 1031.37, 224 | -613.161, 225 | -1618.03, 226 | -115.808, 227 | -866.986, 228 | -1567.2, 229 | 541.587, 230 | 618.034, 231 | -263.146, 232 | 1504.41, 233 | 1504.41, 234 | -263.146, 235 | 618.034, 236 | 541.587, 237 | -1567.2, 238 | -866.986, 239 | -115.808, 240 | -1618.03, 241 | -613.161, 242 | 1031.37, 243 | -101.597, 244 | 450.527, 245 | 2000, 246 | 450.527, 247 | -101.597, 248 | 1031.37, 249 | -613.161, 250 | -1618.03, 251 | -115.808, 252 | -866.986, 253 | -1567.2, 254 | 541.587, 255 | 618.034, 256 | -263.146, 257 | 1504.41, 258 | 1504.41, 259 | -263.146, 260 | 618.034, 261 | 541.587, 262 | -1567.2, 263 | -866.986, 264 | -115.808, 265 | -1618.03, 266 | -613.161, 267 | 1031.37, 268 | -101.597, 269 | 450.527, 270 | 2000, 271 | 450.527, 272 | -101.597, 273 | 1031.37, 274 | -613.161, 275 | -1618.03}; 276 | 277 | IIR iir1; 278 | 279 | int main() 280 | { 281 | init(&iir1, 4, coefB, 4, coefA); 282 | printf("init finished\n"); 283 | fflush(stdout); 284 | /* 285 | for (int i = 0; i < 46; i++) { 286 | printf("\ninit %f- %d\n",fir1.H[i],fir1.n); 287 | fflush(stdout); 288 | } 289 | */ 290 | 291 | for (int i = 0; i < 255; i++) 292 | { 293 | float a; 294 | a = filt(&iir1, input[i]); 295 | printf("%f\n", a); 296 | fflush(stdout); 297 | } 298 | 299 | printf("filter finished\n"); 300 | fflush(stdout); 301 | return 0; 302 | } 303 | --------------------------------------------------------------------------------