-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathfir_table_calc.c
78 lines (72 loc) · 2.47 KB
/
fir_table_calc.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/*
* Web based SDR Client for SDRplay
* =============================================================
* Author: DJ0ABR
*
* (c) DJ0ABR
* www.dj0abr.de
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* fir_table_calc.c ... calculate coefficients for a FIR low pass filter
* ====================================================================
*
* sampleRate ... sample rate from the source (i.e. soundcard, SDR...)
* freq_minus3db ... frequency for an attenuation of 3dB
* pcofs ... an empty double buffer with the following length
* length ... number of coeffs to be calculated (must be an odd number !)
*
* Hints for choosing the length:
* - as short as possible for low CPU load
* - 201 looks to be the minimum usable length
* - 301 good medium value
* - 401 sharp good filter
*
* Hints for choosing the freq_minus3db
* - can usually be 10% less than the needed edge depending on the filter length
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "fir_table_calc.h"
double PI2 = 2.0 * M_PI; // 2 * pi
void createLowPassFIRfilter(double sampleRate, double freq_minus3db, double *pcoeffs, int length)
{
if((length & 1) == 0)
{
// terminate program if length is wrong
printf("createLowPassFIRfiler: length MUST be an odd number !\n");
exit(0);
}
// calculate the coeffs
double freq = freq_minus3db / sampleRate;
int mid = floor(length / 2);
double sum = 0;
double val = 0;
for (int i = 0; i < length; i++)
{
if (i == mid)
val = PI2 * freq;
else
{
val = (sin(PI2 * freq * (double)(i - mid)) / (double)(i - mid)) * (0.54 - 0.46 * cos(PI2 * i / (double)(length - 1)));
}
sum += val;
pcoeffs[i] = val;
}
for (int i = 0; i < length; i++)
pcoeffs[i] /= sum;
}