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.
inthalfbandfilterdbfi.h
Go to the documentation of this file.
1 // Copyright (C) 2018 F4EXB //
3 // written by Edouard Griffiths //
4 // //
5 // Float half-band FIR based interpolator and decimator //
6 // This is the double buffer variant //
7 // //
8 // This program is free software; you can redistribute it and/or modify //
9 // it under the terms of the GNU General Public License as published by //
10 // the Free Software Foundation as version 3 of the License, or //
11 // (at your option) any later version. //
12 // //
13 // This program is distributed in the hope that it will be useful, //
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
16 // GNU General Public License V3 for more details. //
17 // //
18 // You should have received a copy of the GNU General Public License //
19 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
21 
22 #ifndef INCLUDE_INTHALFBANDFILTER_DBFI_H
23 #define INCLUDE_INTHALFBANDFILTER_DBFI_H
24 
25 #include <stdint.h>
26 #include "dsp/dsptypes.h"
27 #include "dsp/hbfiltertraits.h"
28 #include "export.h"
29 
30 template<typename AccuType, typename SampleType, uint32_t HBFilterOrder>
32 public:
34 
35  // downsample by 2, return center part of original spectrum
36  bool workDecimateCenter(Sample* sample)
37  {
38  // insert sample into ring-buffer
39  storeSampleFixReal((FixReal) sample->real(), (FixReal) sample->imag());
40 
41  switch(m_state)
42  {
43  case 0:
44  // advance write-pointer
45  advancePointer();
46  // next state
47  m_state = 1;
48  // tell caller we don't have a new sample
49  return false;
50 
51  default:
52  // save result
53  doFIR(sample);
54  // advance write-pointer
55  advancePointer();
56  // next state
57  m_state = 0;
58 
59  // tell caller we have a new sample
60  return true;
61  }
62  }
63 
64  // upsample by 2, return center part of original spectrum - double buffer variant
65  bool workInterpolateCenterZeroStuffing(Sample* sampleIn, Sample *SampleOut)
66  {
67  switch(m_state)
68  {
69  case 0:
70  // insert sample into ring-buffer
71  storeSampleFixReal((FixReal) 0, (FixReal) 0);
72  // save result
73  doFIR(SampleOut);
74  // advance write-pointer
75  advancePointer();
76  // next state
77  m_state = 1;
78  // tell caller we didn't consume the sample
79  return false;
80 
81  default:
82  // insert sample into ring-buffer
83  storeSampleFixReal((FixReal) sampleIn->real(), (FixReal) sampleIn->imag());
84  // save result
85  doFIR(SampleOut);
86  // advance write-pointer
87  advancePointer();
88  // next state
89  m_state = 0;
90  // tell caller we consumed the sample
91  return true;
92  }
93  }
94 
96  bool workInterpolateCenter(Sample* sampleIn, Sample *SampleOut)
97  {
98  switch(m_state)
99  {
100  case 0:
101  // return the middle peak
102  SampleOut->setReal(m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]);
103  SampleOut->setImag(m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]);
104  m_state = 1; // next state
105  return false; // tell caller we didn't consume the sample
106 
107  default:
108  // calculate with non null samples
109  doInterpolateFIR(SampleOut);
110 
111  // insert sample into ring double buffer
112  m_samplesDB[m_ptr][0] = sampleIn->real();
113  m_samplesDB[m_ptr][1] = sampleIn->imag();
114  m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
115  m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
116 
117  // advance pointer
118  if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
119  m_ptr++;
120  } else {
121  m_ptr = 0;
122  }
123 
124  m_state = 0; // next state
125  return true; // tell caller we consumed the sample
126  }
127  }
128 
129  // downsample by 2, return lower half of original spectrum
131  {
132  switch(m_state)
133  {
134  case 0:
135  // insert sample into ring-buffer
136  storeSampleFixReal((FixReal) -sample->imag(), (FixReal) sample->real());
137  // advance write-pointer
138  advancePointer();
139  // next state
140  m_state = 1;
141  // tell caller we don't have a new sample
142  return false;
143 
144  case 1:
145  // insert sample into ring-buffer
146  storeSampleFixReal((FixReal) -sample->real(), (FixReal) -sample->imag());
147  // save result
148  doFIR(sample);
149  // advance write-pointer
150  advancePointer();
151  // next state
152  m_state = 2;
153  // tell caller we have a new sample
154  return true;
155 
156  case 2:
157  // insert sample into ring-buffer
158  storeSampleFixReal((FixReal) sample->imag(), (FixReal) -sample->real());
159  // advance write-pointer
160  advancePointer();
161  // next state
162  m_state = 3;
163  // tell caller we don't have a new sample
164  return false;
165 
166  default:
167  // insert sample into ring-buffer
168  storeSampleFixReal((FixReal) sample->real(), (FixReal) sample->imag());
169  // save result
170  doFIR(sample);
171  // advance write-pointer
172  advancePointer();
173  // next state
174  m_state = 0;
175  // tell caller we have a new sample
176  return true;
177  }
178  }
179 
181  bool workInterpolateLowerHalf(Sample* sampleIn, Sample *sampleOut)
182  {
183  Sample s;
184 
185  switch(m_state)
186  {
187  case 0:
188  // return the middle peak
189  sampleOut->setReal(m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // imag
190  sampleOut->setImag(-m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // - real
191  m_state = 1; // next state
192  return false; // tell caller we didn't consume the sample
193 
194  case 1:
195  // calculate with non null samples
196  doInterpolateFIR(&s);
197  sampleOut->setReal(-s.real());
198  sampleOut->setImag(-s.imag());
199 
200  // insert sample into ring double buffer
201  m_samplesDB[m_ptr][0] = sampleIn->real();
202  m_samplesDB[m_ptr][1] = sampleIn->imag();
203  m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
204  m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
205 
206  // advance pointer
207  if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
208  m_ptr++;
209  } else {
210  m_ptr = 0;
211  }
212 
213  m_state = 2; // next state
214  return true; // tell caller we consumed the sample
215 
216  case 2:
217  // return the middle peak
218  sampleOut->setReal(-m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // - imag
219  sampleOut->setImag(m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // real
220  m_state = 3; // next state
221  return false; // tell caller we didn't consume the sample
222 
223  default:
224  // calculate with non null samples
225  doInterpolateFIR(&s);
226  sampleOut->setReal(s.real());
227  sampleOut->setImag(s.imag());
228 
229  // insert sample into ring double buffer
230  m_samplesDB[m_ptr][0] = sampleIn->real();
231  m_samplesDB[m_ptr][1] = sampleIn->imag();
232  m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
233  m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
234 
235  // advance pointer
236  if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
237  m_ptr++;
238  } else {
239  m_ptr = 0;
240  }
241 
242  m_state = 0; // next state
243  return true; // tell caller we consumed the sample
244  }
245  }
246 
247  // upsample by 2, from lower half of original spectrum - double buffer variant
249  {
250  Sample s;
251 
252  switch(m_state)
253  {
254  case 0:
255  // insert sample into ring-buffer
256  storeSampleFixReal((FixReal) 0, (FixReal) 0);
257 
258  // save result
259  doFIR(&s);
260  sampleOut->setReal(s.imag());
261  sampleOut->setImag(-s.real());
262 
263  // advance write-pointer
264  advancePointer();
265 
266  // next state
267  m_state = 1;
268 
269  // tell caller we didn't consume the sample
270  return false;
271 
272  case 1:
273  // insert sample into ring-buffer
274  storeSampleFixReal((FixReal) sampleIn->real(), (FixReal) sampleIn->imag());
275 
276  // save result
277  doFIR(&s);
278  sampleOut->setReal(-s.real());
279  sampleOut->setImag(-s.imag());
280 
281  // advance write-pointer
282  advancePointer();
283 
284  // next state
285  m_state = 2;
286 
287  // tell caller we consumed the sample
288  return true;
289 
290  case 2:
291  // insert sample into ring-buffer
292  storeSampleFixReal((FixReal) 0, (FixReal) 0);
293 
294  // save result
295  doFIR(&s);
296  sampleOut->setReal(-s.imag());
297  sampleOut->setImag(s.real());
298 
299  // advance write-pointer
300  advancePointer();
301 
302  // next state
303  m_state = 3;
304 
305  // tell caller we didn't consume the sample
306  return false;
307 
308  default:
309  // insert sample into ring-buffer
310  storeSampleFixReal((FixReal) sampleIn->real(), (FixReal) sampleIn->imag());
311 
312  // save result
313  doFIR(&s);
314  sampleOut->setReal(s.real());
315  sampleOut->setImag(s.imag());
316 
317  // advance write-pointer
318  advancePointer();
319 
320  // next state
321  m_state = 0;
322 
323  // tell caller we consumed the sample
324  return true;
325  }
326  }
327 
328  // downsample by 2, return upper half of original spectrum
330  {
331  switch(m_state)
332  {
333  case 0:
334  // insert sample into ring-buffer
335  storeSampleFixReal((FixReal) sample->imag(), (FixReal) -sample->real());
336  // advance write-pointer
337  advancePointer();
338  // next state
339  m_state = 1;
340  // tell caller we don't have a new sample
341  return false;
342 
343  case 1:
344  // insert sample into ring-buffer
345  storeSampleFixReal((FixReal) -sample->real(), (FixReal) -sample->imag());
346  // save result
347  doFIR(sample);
348  // advance write-pointer
349  advancePointer();
350  // next state
351  m_state = 2;
352  // tell caller we have a new sample
353  return true;
354 
355  case 2:
356  // insert sample into ring-buffer
357  storeSampleFixReal((FixReal) -sample->imag(), (FixReal) sample->real());
358  // advance write-pointer
359  advancePointer();
360  // next state
361  m_state = 3;
362  // tell caller we don't have a new sample
363  return false;
364 
365  default:
366  // insert sample into ring-buffer
367  storeSampleFixReal((FixReal) sample->real(), (FixReal) sample->imag());
368  // save result
369  doFIR(sample);
370  // advance write-pointer
371  advancePointer();
372  // next state
373  m_state = 0;
374  // tell caller we have a new sample
375  return true;
376  }
377  }
378 
380  bool workInterpolateUpperHalf(Sample* sampleIn, Sample *sampleOut)
381  {
382  Sample s;
383 
384  switch(m_state)
385  {
386  case 0:
387  // return the middle peak
388  sampleOut->setReal(-m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // - imag
389  sampleOut->setImag(m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // + real
390  m_state = 1; // next state
391  return false; // tell caller we didn't consume the sample
392 
393  case 1:
394  // calculate with non null samples
395  doInterpolateFIR(&s);
396  sampleOut->setReal(-s.real());
397  sampleOut->setImag(-s.imag());
398 
399  // insert sample into ring double buffer
400  m_samplesDB[m_ptr][0] = sampleIn->real();
401  m_samplesDB[m_ptr][1] = sampleIn->imag();
402  m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
403  m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
404 
405  // advance pointer
406  if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
407  m_ptr++;
408  } else {
409  m_ptr = 0;
410  }
411 
412  m_state = 2; // next state
413  return true; // tell caller we consumed the sample
414 
415  case 2:
416  // return the middle peak
417  sampleOut->setReal(m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // + imag
418  sampleOut->setImag(-m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // - real
419  m_state = 3; // next state
420  return false; // tell caller we didn't consume the sample
421 
422  default:
423  // calculate with non null samples
424  doInterpolateFIR(&s);
425  sampleOut->setReal(s.real());
426  sampleOut->setImag(s.imag());
427 
428  // insert sample into ring double buffer
429  m_samplesDB[m_ptr][0] = sampleIn->real();
430  m_samplesDB[m_ptr][1] = sampleIn->imag();
431  m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
432  m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
433 
434  // advance pointer
435  if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
436  m_ptr++;
437  } else {
438  m_ptr = 0;
439  }
440 
441  m_state = 0; // next state
442  return true; // tell caller we consumed the sample
443  }
444  }
445 
446  // upsample by 2, move original spectrum to upper half - double buffer variant
448  {
449  Sample s;
450 
451  switch(m_state)
452  {
453  case 0:
454  // insert sample into ring-buffer
455  storeSampleFixReal((FixReal) 0, (FixReal) 0);
456 
457  // save result
458  doFIR(&s);
459  sampleOut->setReal(-s.imag());
460  sampleOut->setImag(s.real());
461 
462  // advance write-pointer
463  advancePointer();
464 
465  // next state
466  m_state = 1;
467 
468  // tell caller we didn't consume the sample
469  return false;
470 
471  case 1:
472  // insert sample into ring-buffer
473  storeSampleFixReal((FixReal) sampleIn->real(), (FixReal) sampleIn->imag());
474 
475  // save result
476  doFIR(&s);
477  sampleOut->setReal(-s.real());
478  sampleOut->setImag(-s.imag());
479 
480  // advance write-pointer
481  advancePointer();
482 
483  // next state
484  m_state = 2;
485 
486  // tell caller we consumed the sample
487  return true;
488 
489  case 2:
490  // insert sample into ring-buffer
491  storeSampleFixReal((FixReal) 0, (FixReal) 0);
492 
493  // save result
494  doFIR(&s);
495  sampleOut->setReal(s.imag());
496  sampleOut->setImag(-s.real());
497 
498  // advance write-pointer
499  advancePointer();
500 
501  // next state
502  m_state = 3;
503 
504  // tell caller we didn't consume the sample
505  return false;
506 
507  default:
508  // insert sample into ring-buffer
509  storeSampleFixReal((FixReal) sampleIn->real(), (FixReal) sampleIn->imag());
510 
511  // save result
512  doFIR(&s);
513  sampleOut->setReal(s.real());
514  sampleOut->setImag(s.imag());
515 
516  // advance write-pointer
517  advancePointer();
518 
519  // next state
520  m_state = 0;
521 
522  // tell caller we consumed the sample
523  return true;
524  }
525  }
526 
527  void myDecimate(const Sample* sample1, Sample* sample2)
528  {
529  storeSampleFixReal((FixReal) sample1->real(), (FixReal) sample1->imag());
530  advancePointer();
531 
532  storeSampleFixReal((FixReal) sample2->real(), (FixReal) sample2->imag());
533  doFIR(sample2);
534  advancePointer();
535  }
536 
537  void myDecimate(AccuType x1, AccuType y1, AccuType *x2, AccuType *y2)
538  {
539  storeSampleAccu(x1, y1);
540  advancePointer();
541 
542  storeSampleAccu(*x2, *y2);
543  doFIRAccu(x2, y2);
544  advancePointer();
545  }
546 
548  void myInterpolateZeroStuffing(Sample* sample1, Sample* sample2)
549  {
550  storeSampleFixReal((FixReal) sample1->real(), (FixReal) sample1->imag());
551  doFIR(sample1);
552  advancePointer();
553 
554  storeSampleFixReal((FixReal) 0, (FixReal) 0);
555  doFIR(sample2);
556  advancePointer();
557  }
558 
560  void myInterpolate(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2)
561  {
562  // insert sample into ring double buffer
563  m_samplesDB[m_ptr][0] = *x1;
564  m_samplesDB[m_ptr][1] = *y1;
565  m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = *x1;
566  m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = *y1;
567 
568  // advance pointer
569  if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
570  m_ptr++;
571  } else {
572  m_ptr = 0;
573  }
574 
575  // first output sample calculated with the middle peak
576  *x1 = m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0];
577  *y1 = m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1];
578 
579  // second sample calculated with the filter
580  doInterpolateFIR(x2, y2);
581  }
582 
583  void myInterpolateInf(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2, qint32 *x3, qint32 *y3, qint32 *x4, qint32 *y4)
584  {
585  myInterpolate(x1, y1, x2, y2);
586  myInterpolate(x3, y3, x4, y4);
587  // rotation
588  qint32 x;
589  x = *x1;
590  *x1 = *y1;
591  *y1 = -x;
592  *x2 = -*x2;
593  *y2 = -*y2;
594  x = *x3;
595  *x3 = -*y3;
596  *y3 = x;
597  }
598 
599  void myInterpolateSup(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2, qint32 *x3, qint32 *y3, qint32 *x4, qint32 *y4)
600  {
601  myInterpolate(x1, y1, x2, y2);
602  myInterpolate(x3, y3, x4, y4);
603  // rotation
604  qint32 x;
605  x = *x1;
606  *x1 = -*y1;
607  *y1 = x;
608  *x2 = -*x2;
609  *y2 = -*y2;
610  x = *x3;
611  *x3 = *y3;
612  *y3 = -x;
613  }
614 
615 protected:
616  SampleType m_samplesDB[2*(HBFIRFilterTraits<HBFilterOrder>::hbOrder - 1)][2]; // double buffer technique
617  int m_ptr;
618  int m_size;
619  int m_state;
620 
621  void storeSampleFixReal(const FixReal& sampleI, const FixReal& sampleQ)
622  {
623  m_samplesDB[m_ptr][0] = sampleI / SDR_RX_SCALED;
624  m_samplesDB[m_ptr][1] = sampleQ / SDR_RX_SCALED;
625  m_samplesDB[m_ptr + m_size][0] = sampleI / SDR_RX_SCALED;
626  m_samplesDB[m_ptr + m_size][1] = sampleQ / SDR_RX_SCALED;
627  }
628 
629  void storeSampleAccu(AccuType x, AccuType y)
630  {
631  m_samplesDB[m_ptr][0] = x;
632  m_samplesDB[m_ptr][1] = y;
633  m_samplesDB[m_ptr + m_size][0] = x;
634  m_samplesDB[m_ptr + m_size][1] = y;
635  }
636 
638  {
639  m_ptr = m_ptr + 1 < m_size ? m_ptr + 1: 0;
640  }
641 
642  void doFIR(Sample* sample)
643  {
644  int a = m_ptr + m_size; // tip pointer
645  int b = m_ptr + 1; // tail pointer
646  AccuType iAcc = 0;
647  AccuType qAcc = 0;
648 
649  for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder / 4; i++)
650  {
651  iAcc += (m_samplesDB[a][0] + m_samplesDB[b][0]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffsF[i];
652  qAcc += (m_samplesDB[a][1] + m_samplesDB[b][1]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffsF[i];
653  a -= 2;
654  b += 2;
655  }
656 
657  iAcc += m_samplesDB[b-1][0] << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
658  qAcc += m_samplesDB[b-1][1] << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
659 
660  sample->setReal(iAcc*SDR_RX_SCALED);
661  sample->setImag(qAcc*SDR_RX_SCALED);
662  }
663 
664  void doFIRAccu(AccuType *x, AccuType *y)
665  {
666  int a = m_ptr + m_size; // tip pointer
667  int b = m_ptr + 1; // tail pointer
668  AccuType iAcc = 0;
669  AccuType qAcc = 0;
670 
671  for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder / 4; i++)
672  {
673  iAcc += (m_samplesDB[a][0] + m_samplesDB[b][0]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffsF[i];
674  qAcc += (m_samplesDB[a][1] + m_samplesDB[b][1]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffsF[i];
675  a -= 2;
676  b += 2;
677  }
678 
679  iAcc += m_samplesDB[b-1][0] / 2.0;
680  qAcc += m_samplesDB[b-1][1] / 2.0;
681 
682  *x = iAcc; // HB_SHIFT incorrect do not loose the gained bit
683  *y = qAcc;
684  }
685 
686  void doInterpolateFIR(Sample* sample)
687  {
688  qint16 a = m_ptr;
689  qint16 b = m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder / 2) - 1;
690 
691  // go through samples in buffer
692  AccuType iAcc = 0;
693  AccuType qAcc = 0;
694 
695  for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder / 4; i++)
696  {
697  iAcc += (m_samplesDB[a][0] + m_samplesDB[b][0]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffsF[i];
698  qAcc += (m_samplesDB[a][1] + m_samplesDB[b][1]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffsF[i];
699  a++;
700  b--;
701  }
702 
703  sample->setReal(iAcc * SDR_RX_SCALED);
704  sample->setImag(qAcc * SDR_RX_SCALED);
705  }
706 
707  void doInterpolateFIR(qint32 *x, qint32 *y)
708  {
709  qint16 a = m_ptr;
710  qint16 b = m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder / 2) - 1;
711 
712  // go through samples in buffer
713  AccuType iAcc = 0;
714  AccuType qAcc = 0;
715 
716  for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder / 4; i++)
717  {
718  iAcc += (m_samplesDB[a][0] + m_samplesDB[b][0]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffsF[i];
719  qAcc += (m_samplesDB[a][1] + m_samplesDB[b][1]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffsF[i];
720  a++;
721  b--;
722  }
723 
724  *x = iAcc * SDR_RX_SCALED;
725  *y = qAcc * SDR_RX_SCALED;
726  }
727 };
728 
729 template<typename AccuType, typename SampleType, uint32_t HBFilterOrder>
731 {
733 
734  for (int i = 0; i < m_size; i++)
735  {
736  m_samplesDB[i][0] = 0;
737  m_samplesDB[i][1] = 0;
738  }
739 
740  m_ptr = 0;
741  m_state = 0;
742 }
743 
744 #endif // INCLUDE_INTHALFBANDFILTER_DBF_H
void myDecimate(AccuType x1, AccuType y1, AccuType *x2, AccuType *y2)
bool workInterpolateCenter(Sample *sampleIn, Sample *SampleOut)
void myInterpolateInf(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2, qint32 *x3, qint32 *y3, qint32 *x4, qint32 *y4)
void myDecimate(const Sample *sample1, Sample *sample2)
bool workInterpolateLowerHalfZeroStuffing(Sample *sampleIn, Sample *sampleOut)
void doInterpolateFIR(Sample *sample)
void myInterpolate(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2)
bool workInterpolateCenterZeroStuffing(Sample *sampleIn, Sample *SampleOut)
void storeSampleAccu(AccuType x, AccuType y)
bool workInterpolateUpperHalfZeroStuffing(Sample *sampleIn, Sample *sampleOut)
bool workInterpolateUpperHalf(Sample *sampleIn, Sample *sampleOut)
bool workDecimateUpperHalf(Sample *sample)
void storeSampleFixReal(const FixReal &sampleI, const FixReal &sampleQ)
int32_t i
Definition: decimators.h:244
void setImag(FixReal v)
Definition: dsptypes.h:59
void doFIRAccu(AccuType *x, AccuType *y)
void myInterpolateSup(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2, qint32 *x3, qint32 *y3, qint32 *x4, qint32 *y4)
bool workDecimateLowerHalf(Sample *sample)
void setReal(FixReal v)
Definition: dsptypes.h:58
void doInterpolateFIR(qint32 *x, qint32 *y)
FixReal real() const
Definition: dsptypes.h:61
FixReal imag() const
Definition: dsptypes.h:62
bool workDecimateCenter(Sample *sample)
void myInterpolateZeroStuffing(Sample *sample1, Sample *sample2)
#define SDRBASE_API
Definition: export.h:40
#define SDR_RX_SCALED
Definition: dsptypes.h:34
void doFIR(Sample *sample)
qint16 FixReal
Definition: dsptypes.h:35
bool workInterpolateLowerHalf(Sample *sampleIn, Sample *sampleOut)