SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
bandpass.h
Go to the documentation of this file.
1 #ifndef INCLUDE_BANDPASS_H
2 #define INCLUDE_BANDPASS_H
3 
4 #define _USE_MATH_DEFINES
5 #include <math.h>
6 #include "dsp/dsptypes.h"
7 
8 #undef M_PI
9 #define M_PI 3.14159265358979323846
10 
11 template <class Type> class Bandpass {
12 public:
13  Bandpass() : m_ptr(0) { }
14 
15  void create(int nTaps, double sampleRate, double lowCutoff, double highCutoff)
16  {
17  std::vector<Real> taps_lp;
18  std::vector<Real> taps_hp;
19  double wcl = 2.0 * M_PI * lowCutoff;
20  double Wcl = wcl / sampleRate;
21  double wch = 2.0 * M_PI * highCutoff;
22  double Wch = wch / sampleRate;
23  int i;
24 
25  // check constraints
26  if(!(nTaps & 1)) {
27  qDebug("Bandpass filter has to have an odd number of taps");
28  nTaps++;
29  }
30 
31  // make room
32  m_samples.resize(nTaps);
33  for(int i = 0; i < nTaps; i++)
34  m_samples[i] = 0;
35  m_ptr = 0;
36  m_taps.resize(nTaps / 2 + 1);
37  taps_lp.resize(nTaps / 2 + 1);
38  taps_hp.resize(nTaps / 2 + 1);
39 
40  // generate Sinc filter core
41  for(i = 0; i < nTaps / 2 + 1; i++) {
42  if(i == (nTaps - 1) / 2) {
43  taps_lp[i] = Wch / M_PI;
44  taps_hp[i] = -(Wcl / M_PI);
45  }
46  else {
47  taps_lp[i] = sin(((double)i - ((double)nTaps - 1.0) / 2.0) * Wch) / (((double)i - ((double)nTaps - 1.0) / 2.0) * M_PI);
48  taps_hp[i] = -sin(((double)i - ((double)nTaps - 1.0) / 2.0) * Wcl) / (((double)i - ((double)nTaps - 1.0) / 2.0) * M_PI);
49  }
50  }
51 
52  taps_hp[(nTaps - 1) / 2] += 1;
53 
54  // apply Hamming window and combine lowpass and highpass
55  for(i = 0; i < nTaps / 2 + 1; i++) {
56  taps_lp[i] *= 0.54 + 0.46 * cos((2.0 * M_PI * ((double)i - ((double)nTaps - 1.0) / 2.0)) / (double)nTaps);
57  taps_hp[i] *= 0.54 + 0.46 * cos((2.0 * M_PI * ((double)i - ((double)nTaps - 1.0) / 2.0)) / (double)nTaps);
58  m_taps[i] = -(taps_lp[i]+taps_hp[i]);
59  }
60 
61  m_taps[(nTaps - 1) / 2] += 1;
62 
63  // normalize
64  Real sum = 0;
65 
66  for(i = 0; i < (int)m_taps.size() - 1; i++) {
67  sum += m_taps[i] * 2;
68  }
69 
70  sum += m_taps[i];
71 
72  for(i = 0; i < (int)m_taps.size(); i++) {
73  m_taps[i] /= sum;
74  }
75  }
76 
77  Type filter(Type sample)
78  {
79  Type acc = 0;
80  int a = m_ptr;
81  int b = a - 1;
82  int i, n_taps, size;
83 
84  m_samples[m_ptr] = sample;
85  size = m_samples.size(); // Valgrind optim (2)
86 
87  while(b < 0)
88  {
89  b += size;
90  }
91 
92  n_taps = m_taps.size() - 1; // Valgrind optim
93 
94  for(i = 0; i < n_taps; i++)
95  {
96  acc += (m_samples[a] + m_samples[b]) * m_taps[i];
97  a++;
98 
99  while (a >= size)
100  {
101  a -= size;
102  }
103 
104  b--;
105 
106  while(b < 0)
107  {
108  b += size;
109  }
110  }
111 
112  acc += m_samples[a] * m_taps[i];
113 
114  m_ptr++;
115 
116  while (m_ptr >= size)
117  {
118  m_ptr -= size;
119  }
120 
121  return acc;
122  }
123 
124 private:
125  std::vector<Real> m_taps;
126  std::vector<Type> m_samples;
127  int m_ptr;
128 };
129 
130 #endif // INCLUDE_BANDPASS_H
std::vector< Real > m_taps
Definition: bandpass.h:125
Fixed< IntType, IntBits > cos(Fixed< IntType, IntBits > const &x)
Definition: fixed.h:2271
void create(int nTaps, double sampleRate, double lowCutoff, double highCutoff)
Definition: bandpass.h:15
#define M_PI
Definition: bandpass.h:9
Type filter(Type sample)
Definition: bandpass.h:77
Fixed< IntType, IntBits > sin(Fixed< IntType, IntBits > const &x)
Definition: fixed.h:2265
int32_t i
Definition: decimators.h:244
int m_ptr
Definition: bandpass.h:127
Bandpass()
Definition: bandpass.h:13
std::vector< Type > m_samples
Definition: bandpass.h:126
float Real
Definition: dsptypes.h:42