HARDT - The Ham Radio DSP Toolkit
hfilter.h
1 #ifndef __HFILTER_H
2 #define __HFILTER_H
3 
4 #include "hprobe.h"
5 
13 template <class T>
14 class HFilter : public HFilterBase<T>, public HWriter<T>, public HReader<T>, public HWriterConsumer<T>
15 {
16  private:
17 
18  HWriter<T>* _writer;
19  HReader<T>* _reader;
20 
21  HProbe<T>* _probe;
22 
23  T* _buffer;
24 
25  bool _enabled;
26 
27  void Init() {
28 
29  _buffer = new T[_blocksize];
30  HLog("Allocated %d as local buffer", _blocksize * sizeof(T));
31  }
32 
33  protected:
34 
37 
39  HFilter(HWriter<T>* writer, size_t blocksize, HProbe<T>* probe = NULL):
40  _writer(writer),
41  _reader(NULL),
42  _blocksize(blocksize),
43  _probe(probe),
44  _enabled(true) {
45 
46  HLog("HFilter(HWriter*)");
47  Init();
48  }
49 
51  HFilter(HWriterConsumer<T>* consumer, size_t blocksize, HProbe<T>* probe = NULL):
52  _reader(NULL),
53  _blocksize(blocksize),
54  _probe(probe),
55  _enabled(true) {
56 
57  HLog("HFilter(HWriter*)");
58  Init();
59 
60  consumer->SetWriter(this);
61  }
62 
64  HFilter(HReader<T>* reader, size_t blocksize, HProbe<T>* probe = NULL):
65  _writer(NULL),
66  _reader(reader),
67  _blocksize(blocksize),
68  _probe(probe),
69  _enabled(true) {
70 
71  HLog("HFilter(HReader*)");
72  Init();
73  }
74 
76  void SetWriter(HWriter<T>* writer)
77  {
78  _writer = writer;
79  }
80 
81  public:
82 
85  HLog("~HFilter()");
86  delete _buffer;
87  }
88 
90  int Write(T* src, size_t blocksize) {
91 
92  if( blocksize > _blocksize )
93  {
94  HError("Illegal blocksize in Write() to HFilter. Initialized with %d called with %d", _blocksize, blocksize);
95  throw new HFilterIOException("It is not allowed to write more data than the size given at creation of the filter");
96  }
97 
98  if( _enabled ) {
99  Filter(src, _buffer, blocksize);
100  } else {
101  memcpy((void*) _buffer, (void*) src, sizeof(T) * blocksize);
102  }
103  int written = _writer->Write(_buffer, blocksize);
104 
105  if( _probe != NULL )
106  {
107  _probe->Write(_buffer, blocksize);
108  }
109 
110  return written;
111  }
112 
114  int Read(T* dest, size_t blocksize) {
115 
116  if( blocksize > _blocksize )
117  {
118  HError("Illegal blocksize in Read() to HFilter. Initialized with %d called with %d", _blocksize, blocksize);
119  throw new HFilterIOException("It is not possible to read more data than the size given at creation of the filter");
120  }
121 
122  int received = _reader->Read(_buffer, blocksize);
123  if( _enabled ) {
124  Filter(_buffer, dest, received);
125  } else {
126  memcpy((void*) dest, (void*) _buffer, sizeof(T) * blocksize);
127  }
128 
129  if( _probe != NULL )
130  {
131  _probe->Write(_buffer, blocksize);
132  }
133 
134  return received;
135  }
136 
138  virtual void Filter(T* src, T* dest, size_t blocksize) = 0;
139 
141  bool Start() {
142 
143  if( _reader != NULL )
144  {
145  HLog("Calling Start() on reader");
146  return _reader->Start();
147  }
148  if( _writer != NULL )
149  {
150  HLog("Calling Start() on writer");
151  return _writer->Start();
152  }
153  return false;
154  }
155 
157  bool Stop() {
158 
159  if( _reader != NULL )
160  {
161  HLog("Calling Stop() on reader");
162  return _reader->Stop();
163  }
164  if( _writer != NULL )
165  {
166  HLog("Calling Stop() on writer");
167  return _writer->Stop();
168  }
169  return false;
170  }
171 
173  bool Command(HCommand* command) {
174  if( _writer != nullptr ) {
175  return _writer->Command(command);
176  } else if( _reader != nullptr ) {
177  return _reader->Command(command);
178  }
179  return true;
180  }
181 
183  void Enable() {
184  _enabled = true;
185  }
186 
188  void Disable() {
189  _enabled = false;
190  }
191 
193  bool GetEnabled() {
194  return _enabled;
195  }
196 
197  public:
198 
204  static std::vector<float> ReadCoeffsFromFile(std::string filename)
205  {
206  char name[filename.length() + 1];
207  strcpy(name, filename.c_str());
208 
209  return ReadCoeffsFromFile(name);
210  }
211 
217  static std::vector<float> ReadCoeffsFromFile(char* filename)
218  {
219  std::vector<float> coeffs;
220 
221  #define BEGIN 0
222  #define DIGIT 1
223  #define SEPARATOR 2
224  #define JUNK 3
225  #define COMMENT_BEGIN 4
226  #define COMMENT 5
227 
228  std::ifstream coeffsFile(filename);
229  if (coeffsFile.is_open())
230  {
231  try
232  {
233  std::string block;
234 
235  while( !coeffsFile.eof() )
236  {
237  std::getline(coeffsFile, block);
238 
239  int state = BEGIN;
240  std::string washed = "";
241  for( int i = 0; i < block.length(); i++ )
242  {
243  switch(state)
244  {
245  case BEGIN:
246  switch(block[i])
247  {
248  case '0':
249  case '1':
250  case '2':
251  case '3':
252  case '4':
253  case '5':
254  case '6':
255  case '7':
256  case '8':
257  case '9':
258  case '-':
259  case '+':
260  state = DIGIT;
261  washed += block[i];
262  break;
263  case ' ':
264  case ',':
265  case ';':
266  state = SEPARATOR;
267  break;
268  case '/':
269  state = COMMENT_BEGIN;
270  break;
271  default:
272  state = JUNK;
273  break;
274  }
275  break;
276 
277  case DIGIT:
278  switch(block[i]) {
279  case '0':
280  case '1':
281  case '2':
282  case '3':
283  case '4':
284  case '5':
285  case '6':
286  case '7':
287  case '8':
288  case '9':
289  case '.':
290  state = DIGIT;
291  washed += block[i];
292  break;
293  case ' ':
294  case ',':
295  case ';':
296  if( washed.length() > 0 ) {
297  coeffs.push_back(std::stof(washed));
298  washed = "";
299  }
300  state = SEPARATOR;
301  break;
302  case '/':
303  if( washed.length() > 0 ) {
304  coeffs.push_back(std::stof(washed));
305  washed = "";
306  }
307  state = COMMENT_BEGIN;
308  break;
309  default:
310  if( washed.length() > 0 ) {
311  coeffs.push_back(std::stof(washed));
312  washed = "";
313  }
314  state = JUNK;
315  break;
316  }
317  break;
318 
319  case SEPARATOR:
320  switch(block[i]) {
321  case '0':
322  case '1':
323  case '2':
324  case '3':
325  case '4':
326  case '5':
327  case '6':
328  case '7':
329  case '8':
330  case '9':
331  case '-':
332  case '+':
333  state = DIGIT;
334  washed += block[i];
335  break;
336  case ' ':
337  case ',':
338  case ';':
339  state = SEPARATOR;
340  break;
341  default:
342  state = JUNK;
343  break;
344  }
345  break;
346 
347  case JUNK:
348  switch(block[i])
349  {
350  case ' ':
351  case ',':
352  case ';':
353  state = SEPARATOR;
354  break;
355  default:
356  state = JUNK;
357  break;
358  }
359 
360  case COMMENT_BEGIN:
361  switch(block[i]) {
362  case '/':
363  state = COMMENT;
364  break;
365  default:
366  state = JUNK;
367  break;
368  }
369  break;
370 
371  case COMMENT:
372  state = COMMENT;
373  }
374  }
375 
376  // Add remaining digits, if we are still reading digits
377  if( state == DIGIT && washed.length() > 0 )
378  {
379  coeffs.push_back(std::stof(washed));
380  }
381  }
382  }
383  catch( std::exception* ex )
384  {
385  HError("Caught exception while reading coefficients file: %s", ex->what());
386  throw new HFilterInitializationException("Exception while reading coefficients from file");
387  }
388  catch( ... )
389  {
390  HError("Caught unknown exception while reading coefficients file");
391  throw new HFilterInitializationException("Exception while reading coefficients from file");
392  }
393  }
394  else
395  {
396  HError("No such file %s", filename);
397  throw new HFilterInitializationException("Coefficients file not found");
398  }
399  coeffsFile.close();
400 
401  return coeffs;
402  }
403 
404 };
405 
406 #endif
HReader::Command
virtual bool Command(HCommand *command)=0
HFilterIOException
Definition: hexceptions.h:151
HFilterBase
Definition: hfilterbase.h:18
HFilter::Filter
virtual void Filter(T *src, T *dest, size_t blocksize)=0
HFilter::Stop
bool Stop()
Definition: hfilter.h:157
HFilter::HFilter
HFilter(HWriterConsumer< T > *consumer, size_t blocksize, HProbe< T > *probe=NULL)
Definition: hfilter.h:51
HFilter::HFilter
HFilter(HReader< T > *reader, size_t blocksize, HProbe< T > *probe=NULL)
Definition: hfilter.h:64
HFilter::~HFilter
~HFilter()
Definition: hfilter.h:84
HFilter::Disable
void Disable()
Definition: hfilter.h:188
HReader::Stop
virtual bool Stop()
Definition: hreader.h:41
HWriter
Definition: hwriter.h:10
HFilter::Command
bool Command(HCommand *command)
Definition: hfilter.h:173
HWriterConsumer::SetWriter
virtual void SetWriter(HWriter< T > *writer)=0
HFilter
Definition: hfilter.h:14
HWriter::Write
virtual int Write(T *src, size_t blocksize)=0
HFilter::ReadCoeffsFromFile
static std::vector< float > ReadCoeffsFromFile(std::string filename)
Definition: hfilter.h:204
HReader::Start
virtual bool Start()
Definition: hreader.h:35
HFilter::Enable
void Enable()
Definition: hfilter.h:183
HWriter::Command
virtual bool Command(HCommand *command)=0
HReader
Definition: hreader.h:24
HFilter::Write
int Write(T *src, size_t blocksize)
Definition: hfilter.h:90
HWriter::Start
virtual bool Start()
Definition: hwriter.h:21
HProbe
Definition: hprobe.h:10
HFilter::_blocksize
int _blocksize
Definition: hfilter.h:36
HFilter::HFilter
HFilter(HWriter< T > *writer, size_t blocksize, HProbe< T > *probe=NULL)
Definition: hfilter.h:39
HFilter::Start
bool Start()
Definition: hfilter.h:141
HCommand
Definition: hcommand.h:81
HFilter::SetWriter
void SetWriter(HWriter< T > *writer)
Definition: hfilter.h:76
HReader::Read
virtual int Read(T *dest, size_t blocksize)=0
HFilter::ReadCoeffsFromFile
static std::vector< float > ReadCoeffsFromFile(char *filename)
Definition: hfilter.h:217
HWriter::Stop
virtual bool Stop()
Definition: hwriter.h:27
HFilter::GetEnabled
bool GetEnabled()
Definition: hfilter.h:193
HFilterInitializationException
Definition: hexceptions.h:165
HFilter::Read
int Read(T *dest, size_t blocksize)
Definition: hfilter.h:114
HProbe::Write
int Write(T *src, size_t blocksize)
Definition: hprobe.h:40
HWriterConsumer
Definition: hwriterconsumer.h:8