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.
inthalfbandfiltereo.h
Go to the documentation of this file.
1 // Copyright (C) 2018 F4EXB //
3 // written by Edouard Griffiths //
4 // //
5 // Integer half-band FIR based interpolator and decimator //
6 // This is the even/odd double buffer variant. Really useful only when SIMD is //
7 // used //
8 // //
9 // This program is free software; you can redistribute it and/or modify //
10 // it under the terms of the GNU General Public License as published by //
11 // the Free Software Foundation as version 3 of the License, or //
12 // (at your option) any later version. //
13 // //
14 // This program is distributed in the hope that it will be useful, //
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
17 // GNU General Public License V3 for more details. //
18 // //
19 // You should have received a copy of the GNU General Public License //
20 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
22 
23 #ifndef SDRBASE_DSP_INTHALFBANDFILTEREO_H_
24 #define SDRBASE_DSP_INTHALFBANDFILTEREO_H_
25 
26 #include <stdint.h>
27 #include <cstdlib>
28 #include "dsp/dsptypes.h"
29 #include "dsp/hbfiltertraits.h"
30 
31 template<typename EOStorageType, typename AccuType, uint32_t HBFilterOrder>
33 public:
35  {
37 
38  for (int i = 0; i < 2*m_size; i++)
39  {
40  m_even[0][i] = 0;
41  m_even[1][i] = 0;
42  m_odd[0][i] = 0;
43  m_odd[1][i] = 0;
44  m_samples[i][0] = 0;
45  m_samples[i][1] = 0;
46  }
47 
48  m_ptr = 0;
49  m_state = 0;
50  }
51 
52  // downsample by 2, return center part of original spectrum
53  bool workDecimateCenter(Sample* sample)
54  {
55  // insert sample into ring-buffer
56  storeSample((FixReal) sample->real(), (FixReal) sample->imag());
57 
58  switch(m_state)
59  {
60  case 0:
61  // advance write-pointer
63  // next state
64  m_state = 1;
65  // tell caller we don't have a new sample
66  return false;
67 
68  default:
69  // save result
70  doFIR(sample);
71  // advance write-pointer
73  // next state
74  m_state = 0;
75 
76  // tell caller we have a new sample
77  return true;
78  }
79  }
80 
81  // upsample by 2, return center part of original spectrum - double buffer variant
82  bool workInterpolateCenterZeroStuffing(Sample* sampleIn, Sample *SampleOut)
83  {
84  switch(m_state)
85  {
86  case 0:
87  // insert sample into ring-buffer
88  storeSample((FixReal) 0, (FixReal) 0);
89  // save result
90  doFIR(SampleOut);
91  // advance write-pointer
93  // next state
94  m_state = 1;
95  // tell caller we didn't consume the sample
96  return false;
97 
98  default:
99  // insert sample into ring-buffer
100  storeSample((FixReal) sampleIn->real(), (FixReal) sampleIn->imag());
101  // save result
102  doFIR(SampleOut);
103  // advance write-pointer
104  advancePointer();
105  // next state
106  m_state = 0;
107  // tell caller we consumed the sample
108  return true;
109  }
110  }
111 
113  bool workInterpolateCenter(Sample* sampleIn, Sample *SampleOut)
114  {
115  switch(m_state)
116  {
117  case 0:
118  // return the middle peak
121  m_state = 1; // next state
122  return false; // tell caller we didn't consume the sample
123 
124  default:
125  // calculate with non null samples
126  doInterpolateFIR(SampleOut);
127 
128  // insert sample into ring double buffer
129  m_samples[m_ptr][0] = sampleIn->real();
130  m_samples[m_ptr][1] = sampleIn->imag();
133 
134  // advance pointer
136  m_ptr++;
137  } else {
138  m_ptr = 0;
139  }
140 
141  m_state = 0; // next state
142  return true; // tell caller we consumed the sample
143  }
144  }
145 
147  {
148  // insert sample into ring-buffer
149  storeSample32(*x, *y);
150 
151  switch(m_state)
152  {
153  case 0:
154  // advance write-pointer
155  advancePointer();
156  // next state
157  m_state = 1;
158  // tell caller we don't have a new sample
159  return false;
160 
161  default:
162  // save result
163  doFIR(x, y);
164  // advance write-pointer
165  advancePointer();
166  // next state
167  m_state = 0;
168  // tell caller we have a new sample
169  return true;
170  }
171  }
172 
173  // downsample by 2, return lower half of original spectrum
175  {
176  switch(m_state)
177  {
178  case 0:
179  // insert sample into ring-buffer
180  storeSample((FixReal) -sample->imag(), (FixReal) sample->real());
181  // advance write-pointer
182  advancePointer();
183  // next state
184  m_state = 1;
185  // tell caller we don't have a new sample
186  return false;
187 
188  case 1:
189  // insert sample into ring-buffer
190  storeSample((FixReal) -sample->real(), (FixReal) -sample->imag());
191  // save result
192  doFIR(sample);
193  // advance write-pointer
194  advancePointer();
195  // next state
196  m_state = 2;
197  // tell caller we have a new sample
198  return true;
199 
200  case 2:
201  // insert sample into ring-buffer
202  storeSample((FixReal) sample->imag(), (FixReal) -sample->real());
203  // advance write-pointer
204  advancePointer();
205  // next state
206  m_state = 3;
207  // tell caller we don't have a new sample
208  return false;
209 
210  default:
211  // insert sample into ring-buffer
212  storeSample((FixReal) sample->real(), (FixReal) sample->imag());
213  // save result
214  doFIR(sample);
215  // advance write-pointer
216  advancePointer();
217  // next state
218  m_state = 0;
219  // tell caller we have a new sample
220  return true;
221  }
222  }
223 
224  // upsample by 2, from lower half of original spectrum - double buffer variant
226  {
227  Sample s;
228 
229  switch(m_state)
230  {
231  case 0:
232  // insert sample into ring-buffer
233  storeSample((FixReal) 0, (FixReal) 0);
234 
235  // save result
236  doFIR(&s);
237  sampleOut->setReal(s.imag());
238  sampleOut->setImag(-s.real());
239 
240  // advance write-pointer
241  advancePointer();
242 
243  // next state
244  m_state = 1;
245 
246  // tell caller we didn't consume the sample
247  return false;
248 
249  case 1:
250  // insert sample into ring-buffer
251  storeSample((FixReal) sampleIn->real(), (FixReal) sampleIn->imag());
252 
253  // save result
254  doFIR(&s);
255  sampleOut->setReal(-s.real());
256  sampleOut->setImag(-s.imag());
257 
258  // advance write-pointer
259  advancePointer();
260 
261  // next state
262  m_state = 2;
263 
264  // tell caller we consumed the sample
265  return true;
266 
267  case 2:
268  // insert sample into ring-buffer
269  storeSample((FixReal) 0, (FixReal) 0);
270 
271  // save result
272  doFIR(&s);
273  sampleOut->setReal(-s.imag());
274  sampleOut->setImag(s.real());
275 
276  // advance write-pointer
277  advancePointer();
278 
279  // next state
280  m_state = 3;
281 
282  // tell caller we didn't consume the sample
283  return false;
284 
285  default:
286  // insert sample into ring-buffer
287  storeSample((FixReal) sampleIn->real(), (FixReal) sampleIn->imag());
288 
289  // save result
290  doFIR(&s);
291  sampleOut->setReal(s.real());
292  sampleOut->setImag(s.imag());
293 
294  // advance write-pointer
295  advancePointer();
296 
297  // next state
298  m_state = 0;
299 
300  // tell caller we consumed the sample
301  return true;
302  }
303  }
304 
306  bool workInterpolateLowerHalf(Sample* sampleIn, Sample *sampleOut)
307  {
308  Sample s;
309 
310  switch(m_state)
311  {
312  case 0:
313  // return the middle peak
314  sampleOut->setReal(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // imag
315  sampleOut->setImag(-m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // - real
316  m_state = 1; // next state
317  return false; // tell caller we didn't consume the sample
318 
319  case 1:
320  // calculate with non null samples
321  doInterpolateFIR(&s);
322  sampleOut->setReal(-s.real());
323  sampleOut->setImag(-s.imag());
324 
325  // insert sample into ring double buffer
326  m_samples[m_ptr][0] = sampleIn->real();
327  m_samples[m_ptr][1] = sampleIn->imag();
330 
331  // advance pointer
333  m_ptr++;
334  } else {
335  m_ptr = 0;
336  }
337 
338  m_state = 2; // next state
339  return true; // tell caller we consumed the sample
340 
341  case 2:
342  // return the middle peak
343  sampleOut->setReal(-m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // - imag
344  sampleOut->setImag(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // real
345  m_state = 3; // next state
346  return false; // tell caller we didn't consume the sample
347 
348  default:
349  // calculate with non null samples
350  doInterpolateFIR(&s);
351  sampleOut->setReal(s.real());
352  sampleOut->setImag(s.imag());
353 
354  // insert sample into ring double buffer
355  m_samples[m_ptr][0] = sampleIn->real();
356  m_samples[m_ptr][1] = sampleIn->imag();
359 
360  // advance pointer
362  m_ptr++;
363  } else {
364  m_ptr = 0;
365  }
366 
367  m_state = 0; // next state
368  return true; // tell caller we consumed the sample
369  }
370  }
371 
372  // downsample by 2, return upper half of original spectrum
374  {
375  switch(m_state)
376  {
377  case 0:
378  // insert sample into ring-buffer
379  storeSample((FixReal) sample->imag(), (FixReal) -sample->real());
380  // advance write-pointer
381  advancePointer();
382  // next state
383  m_state = 1;
384  // tell caller we don't have a new sample
385  return false;
386 
387  case 1:
388  // insert sample into ring-buffer
389  storeSample((FixReal) -sample->real(), (FixReal) -sample->imag());
390  // save result
391  doFIR(sample);
392  // advance write-pointer
393  advancePointer();
394  // next state
395  m_state = 2;
396  // tell caller we have a new sample
397  return true;
398 
399  case 2:
400  // insert sample into ring-buffer
401  storeSample((FixReal) -sample->imag(), (FixReal) sample->real());
402  // advance write-pointer
403  advancePointer();
404  // next state
405  m_state = 3;
406  // tell caller we don't have a new sample
407  return false;
408 
409  default:
410  // insert sample into ring-buffer
411  storeSample((FixReal) sample->real(), (FixReal) sample->imag());
412  // save result
413  doFIR(sample);
414  // advance write-pointer
415  advancePointer();
416  // next state
417  m_state = 0;
418  // tell caller we have a new sample
419  return true;
420  }
421  }
422 
423  // upsample by 2, move original spectrum to upper half - double buffer variant
425  {
426  Sample s;
427 
428  switch(m_state)
429  {
430  case 0:
431  // insert sample into ring-buffer
432  storeSample((FixReal) 0, (FixReal) 0);
433 
434  // save result
435  doFIR(&s);
436  sampleOut->setReal(-s.imag());
437  sampleOut->setImag(s.real());
438 
439  // advance write-pointer
440  advancePointer();
441 
442  // next state
443  m_state = 1;
444 
445  // tell caller we didn't consume the sample
446  return false;
447 
448  case 1:
449  // insert sample into ring-buffer
450  storeSample((FixReal) sampleIn->real(), (FixReal) sampleIn->imag());
451 
452  // save result
453  doFIR(&s);
454  sampleOut->setReal(-s.real());
455  sampleOut->setImag(-s.imag());
456 
457  // advance write-pointer
458  advancePointer();
459 
460  // next state
461  m_state = 2;
462 
463  // tell caller we consumed the sample
464  return true;
465 
466  case 2:
467  // insert sample into ring-buffer
468  storeSample((FixReal) 0, (FixReal) 0);
469 
470  // save result
471  doFIR(&s);
472  sampleOut->setReal(s.imag());
473  sampleOut->setImag(-s.real());
474 
475  // advance write-pointer
476  advancePointer();
477 
478  // next state
479  m_state = 3;
480 
481  // tell caller we didn't consume the sample
482  return false;
483 
484  default:
485  // insert sample into ring-buffer
486  storeSample((FixReal) sampleIn->real(), (FixReal) sampleIn->imag());
487 
488  // save result
489  doFIR(&s);
490  sampleOut->setReal(s.real());
491  sampleOut->setImag(s.imag());
492 
493  // advance write-pointer
494  advancePointer();
495 
496  // next state
497  m_state = 0;
498 
499  // tell caller we consumed the sample
500  return true;
501  }
502  }
503 
505  bool workInterpolateUpperHalf(Sample* sampleIn, Sample *sampleOut)
506  {
507  Sample s;
508 
509  switch(m_state)
510  {
511  case 0:
512  // return the middle peak
513  sampleOut->setReal(-m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // - imag
514  sampleOut->setImag(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // + real
515  m_state = 1; // next state
516  return false; // tell caller we didn't consume the sample
517 
518  case 1:
519  // calculate with non null samples
520  doInterpolateFIR(&s);
521  sampleOut->setReal(-s.real());
522  sampleOut->setImag(-s.imag());
523 
524  // insert sample into ring double buffer
525  m_samples[m_ptr][0] = sampleIn->real();
526  m_samples[m_ptr][1] = sampleIn->imag();
529 
530  // advance pointer
532  m_ptr++;
533  } else {
534  m_ptr = 0;
535  }
536 
537  m_state = 2; // next state
538  return true; // tell caller we consumed the sample
539 
540  case 2:
541  // return the middle peak
542  sampleOut->setReal(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // + imag
543  sampleOut->setImag(-m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // - real
544  m_state = 3; // next state
545  return false; // tell caller we didn't consume the sample
546 
547  default:
548  // calculate with non null samples
549  doInterpolateFIR(&s);
550  sampleOut->setReal(s.real());
551  sampleOut->setImag(s.imag());
552 
553  // insert sample into ring double buffer
554  m_samples[m_ptr][0] = sampleIn->real();
555  m_samples[m_ptr][1] = sampleIn->imag();
558 
559  // advance pointer
561  m_ptr++;
562  } else {
563  m_ptr = 0;
564  }
565 
566  m_state = 0; // next state
567  return true; // tell caller we consumed the sample
568  }
569  }
570 
571  void myDecimate(const Sample* sample1, Sample* sample2)
572  {
573  storeSample((FixReal) sample1->real(), (FixReal) sample1->imag());
574  advancePointer();
575 
576  storeSample((FixReal) sample2->real(), (FixReal) sample2->imag());
577  doFIR(sample2);
578  advancePointer();
579  }
580 
581  void myDecimate(int32_t x1, int32_t y1, int32_t *x2, int32_t *y2)
582  {
583  storeSample32(x1, y1);
584  advancePointer();
585 
586  storeSample32(*x2, *y2);
587  doFIR(x2, y2);
588  advancePointer();
589  }
590 
591  void myDecimateCen(int32_t x1, int32_t y1, int32_t *x2, int32_t *y2, int32_t x3, int32_t y3, int32_t *x4, int32_t *y4)
592  {
593  storeSample32(x1, y1);
594  advancePointer();
595 
596  storeSample32(*x2, *y2);
597  doFIR(x2, y2);
598  advancePointer();
599 
600  storeSample32(x3, y3);
601  advancePointer();
602 
603  storeSample32(*x4, *y4);
604  doFIR(x4, y4);
605  advancePointer();
606  }
607 
608  void myDecimateCen(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x3, int32_t y3, int32_t x4, int32_t y4, int32_t *out)
609  {
610  storeSample32(x1, y1);
611  advancePointer();
612 
613  storeSample32(x2, y2);
614  doFIR(&out[0], &out[1]);
615  advancePointer();
616 
617  storeSample32(x3, y3);
618  advancePointer();
619 
620  storeSample32(x4, y4);
621  doFIR(&out[2], &out[3]);
622  advancePointer();
623  }
624 
625  void myDecimateCen(int32_t *in, int32_t *out)
626  {
627  storeSample32(in[0], in[1]);
628  advancePointer();
629 
630  storeSample32(in[2], in[3]);
631  doFIR(&out[0], &out[1]);
632  advancePointer();
633 
634  storeSample32(in[4], in[5]);
635  advancePointer();
636 
637  storeSample32(in[6], in[7]);
638  doFIR(&out[2], &out[3]);
639  advancePointer();
640  }
641 
642  void myDecimateInf(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x3, int32_t y3, int32_t x4, int32_t y4, int32_t *out)
643  {
644  storeSample32(-y1, x1);
645  advancePointer();
646 
647  storeSample32(-x2, -y2);
648  doFIR(&out[0], &out[1]);
649  advancePointer();
650 
651  storeSample32(y3, -x3);
652  advancePointer();
653 
654  storeSample32(x4, y4);
655  doFIR(&out[2], &out[3]);
656  advancePointer();
657  }
658 
659  void myDecimateInf(int32_t *in, int32_t *out)
660  {
661  storeSample32(-in[1], in[0]);
662  advancePointer();
663 
664  storeSample32(-in[2], -in[3]);
665  doFIR(&out[0], &out[1]);
666  advancePointer();
667 
668  storeSample32(in[5], -in[4]);
669  advancePointer();
670 
671  storeSample32(in[6], in[7]);
672  doFIR(&out[2], &out[3]);
673  advancePointer();
674  }
675 
676  void myDecimateSup(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x3, int32_t y3, int32_t x4, int32_t y4, int32_t *out)
677  {
678  storeSample32(y1, -x1);
679  advancePointer();
680 
681  storeSample32(-x2, -y2);
682  doFIR(&out[0], &out[1]);
683  advancePointer();
684 
685  storeSample32(-y3, x3);
686  advancePointer();
687 
688  storeSample32(x4, y4);
689  doFIR(&out[2], &out[3]);
690  advancePointer();
691  }
692 
693  void myDecimateSup(int32_t *in, int32_t *out)
694  {
695  storeSample32(in[1], -in[0]);
696  advancePointer();
697 
698  storeSample32(-in[2], -in[3]);
699  doFIR(&out[0], &out[1]);
700  advancePointer();
701 
702  storeSample32(-in[5], in[4]);
703  advancePointer();
704 
705  storeSample32(in[6], in[7]);
706  doFIR(&out[2], &out[3]);
707  advancePointer();
708  }
709 
711  void myInterpolateZeroStuffing(Sample* sample1, Sample* sample2)
712  {
713  storeSample((FixReal) sample1->real(), (FixReal) sample1->imag());
714  doFIR(sample1);
715  advancePointer();
716 
717  storeSample((FixReal) 0, (FixReal) 0);
718  doFIR(sample2);
719  advancePointer();
720  }
721 
724  {
725  storeSample32(*x1, *y1);
726  doFIR(x1, y1);
727  advancePointer();
728 
729  storeSample32(0, 0);
730  doFIR(x2, y2);
731  advancePointer();
732  }
733 
735  void myInterpolate(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2)
736  {
737  // insert sample into ring double buffer
738  m_samples[m_ptr][0] = *x1;
739  m_samples[m_ptr][1] = *y1;
742 
743  // advance pointer
745  m_ptr++;
746  } else {
747  m_ptr = 0;
748  }
749 
750  // first output sample calculated with the middle peak
753 
754  // second sample calculated with the filter
755  doInterpolateFIR(x2, y2);
756  }
757 
758  void myInterpolateInf(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2, qint32 *x3, qint32 *y3, qint32 *x4, qint32 *y4)
759  {
760  myInterpolate(x1, y1, x2, y2);
761  myInterpolate(x3, y3, x4, y4);
762  // rotation
763  qint32 x;
764  x = *x1;
765  *x1 = *y1;
766  *y1 = -x;
767  *x2 = -*x2;
768  *y2 = -*y2;
769  x = *x3;
770  *x3 = -*y3;
771  *y3 = x;
772  }
773 
774  void myInterpolateSup(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2, qint32 *x3, qint32 *y3, qint32 *x4, qint32 *y4)
775  {
776  myInterpolate(x1, y1, x2, y2);
777  myInterpolate(x3, y3, x4, y4);
778  // rotation
779  qint32 x;
780  x = *x1;
781  *x1 = -*y1;
782  *y1 = x;
783  *x2 = -*x2;
784  *y2 = -*y2;
785  x = *x3;
786  *x3 = *y3;
787  *y3 = -x;
788  }
789 
790 protected:
794 
795  int m_ptr;
796  int m_size;
797  int m_state;
798 
799  void storeSample(const FixReal& sampleI, const FixReal& sampleQ)
800  {
801  if ((m_ptr % 2) == 0)
802  {
803  m_even[0][m_ptr/2] = sampleI;
804  m_even[1][m_ptr/2] = sampleQ;
805  m_even[0][m_ptr/2 + m_size] = sampleI;
806  m_even[1][m_ptr/2 + m_size] = sampleQ;
807  }
808  else
809  {
810  m_odd[0][m_ptr/2] = sampleI;
811  m_odd[1][m_ptr/2] = sampleQ;
812  m_odd[0][m_ptr/2 + m_size] = sampleI;
813  m_odd[1][m_ptr/2 + m_size] = sampleQ;
814  }
815  }
816 
818  {
819  if ((m_ptr % 2) == 0)
820  {
821  m_even[0][m_ptr/2] = x;
822  m_even[1][m_ptr/2] = y;
823  m_even[0][m_ptr/2 + m_size] = x;
824  m_even[1][m_ptr/2 + m_size] = y;
825  }
826  else
827  {
828  m_odd[0][m_ptr/2] = x;
829  m_odd[1][m_ptr/2] = y;
830  m_odd[0][m_ptr/2 + m_size] = x;
831  m_odd[1][m_ptr/2 + m_size] = y;
832  }
833  }
834 
836  {
837  m_ptr = m_ptr + 1 < 2*m_size ? m_ptr + 1: 0;
838  }
839 
840  void doFIR(Sample* sample)
841  {
842  AccuType iAcc = 0;
843  AccuType qAcc = 0;
844 
845  int a = m_ptr/2 + m_size; // tip pointer
846  int b = m_ptr/2 + 1; // tail pointer
847 
848  for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder / 4; i++)
849  {
850  if ((m_ptr % 2) == 0)
851  {
852  iAcc += ((EOStorageType)(m_even[0][a] + m_even[0][b])) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
853  qAcc += ((EOStorageType)(m_even[1][a] + m_even[1][b])) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
854  }
855  else
856  {
857  iAcc += ((EOStorageType)(m_odd[0][a] + m_odd[0][b])) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
858  qAcc += ((EOStorageType)(m_odd[1][a] + m_odd[1][b])) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
859  }
860 
861  a -= 1;
862  b += 1;
863  }
864 
865  if ((m_ptr % 2) == 0)
866  {
867  iAcc += m_odd[0][m_ptr/2 + m_size/2] << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
868  qAcc += m_odd[1][m_ptr/2 + m_size/2] << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
869  }
870  else
871  {
872  iAcc += m_even[0][m_ptr/2 + m_size/2 + 1] << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
873  qAcc += m_even[1][m_ptr/2 + m_size/2 + 1] << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
874  }
875 
878  }
879 
880  void doFIR(int32_t *x, int32_t *y)
881  {
882  AccuType iAcc = 0;
883  AccuType qAcc = 0;
884 
885  int a = m_ptr/2 + m_size; // tip pointer
886  int b = m_ptr/2 + 1; // tail pointer
887 
888  for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder / 4; i++)
889  {
890  if ((m_ptr % 2) == 0)
891  {
892  iAcc += ((EOStorageType)(m_even[0][a] + m_even[0][b])) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
893  qAcc += ((EOStorageType)(m_even[1][a] + m_even[1][b])) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
894  }
895  else
896  {
897  iAcc += ((EOStorageType)(m_odd[0][a] + m_odd[0][b])) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
898  qAcc += ((EOStorageType)(m_odd[1][a] + m_odd[1][b])) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
899  }
900 
901  a -= 1;
902  b += 1;
903  }
904 
905  if ((m_ptr % 2) == 0)
906  {
907  iAcc += m_odd[0][m_ptr/2 + m_size/2] << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
908  qAcc += m_odd[1][m_ptr/2 + m_size/2] << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
909  }
910  else
911  {
912  iAcc += m_even[0][m_ptr/2 + m_size/2 + 1] << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
913  qAcc += m_even[1][m_ptr/2 + m_size/2 + 1] << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
914  }
915 
916  *x = iAcc >> (HBFIRFilterTraits<HBFilterOrder>::hbShift -1); // HB_SHIFT incorrect do not loose the gained bit
918  }
919 
920  void doInterpolateFIR(Sample* sample)
921  {
922  AccuType iAcc = 0;
923  AccuType qAcc = 0;
924 
925  qint16 a = m_ptr;
926  qint16 b = m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder / 2) - 1;
927 
928  // go through samples in buffer
929  for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder / 4; i++)
930  {
931  iAcc += ((EOStorageType)(m_samples[a][0] + m_samples[b][0])) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
932  qAcc += ((EOStorageType)(m_samples[a][1] + m_samples[b][1])) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
933  a++;
934  b--;
935  }
936 
939  }
940 
941  void doInterpolateFIR(qint32 *x, qint32 *y)
942  {
943  AccuType iAcc = 0;
944  AccuType qAcc = 0;
945 
946  qint16 a = m_ptr;
947  qint16 b = m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder / 2) - 1;
948 
949  // go through samples in buffer
950  for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder / 4; i++)
951  {
952  iAcc += ((EOStorageType)(m_samples[a][0] + m_samples[b][0])) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
953  qAcc += ((EOStorageType)(m_samples[a][1] + m_samples[b][1])) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
954  a++;
955  b--;
956  }
957 
960  }
961 };
962 
963 //template<typename EOStorageType, typename AccuType, uint32_t HBFilterOrder>
964 //IntHalfbandFilterEO<EOStorageType, AccuType, HBFilterOrder>::IntHalfbandFilterEO()
965 //{
966 // m_size = HBFIRFilterTraits<HBFilterOrder>::hbOrder/2;
967 
968 // for (int i = 0; i < 2*m_size; i++)
969 // {
970 // m_even[0][i] = 0;
971 // m_even[1][i] = 0;
972 // m_odd[0][i] = 0;
973 // m_odd[1][i] = 0;
974 // m_samples[i][0] = 0;
975 // m_samples[i][1] = 0;
976 // }
977 
978 // m_ptr = 0;
979 // m_state = 0;
980 //}
981 
982 #endif /* SDRBASE_DSP_INTHALFBANDFILTEREO_H_ */
void myDecimateSup(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x3, int32_t y3, int32_t x4, int32_t y4, int32_t *out)
void myDecimateCen(int32_t x1, int32_t y1, int32_t *x2, int32_t *y2, int32_t x3, int32_t y3, int32_t *x4, int32_t *y4)
void doFIR(Sample *sample)
void myDecimateSup(int32_t *in, int32_t *out)
void myDecimate(int32_t x1, int32_t y1, int32_t *x2, int32_t *y2)
bool workDecimateCenter(int32_t *x, int32_t *y)
bool workInterpolateLowerHalfZeroStuffing(Sample *sampleIn, Sample *sampleOut)
void myDecimateCen(int32_t *in, int32_t *out)
void storeSample32(int32_t x, int32_t y)
void myInterpolateZeroStuffing(Sample *sample1, Sample *sample2)
bool workInterpolateLowerHalf(Sample *sampleIn, Sample *sampleOut)
bool workInterpolateCenterZeroStuffing(Sample *sampleIn, Sample *SampleOut)
void myDecimateInf(int32_t *in, int32_t *out)
void myInterpolate(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2)
bool workDecimateLowerHalf(Sample *sample)
void doInterpolateFIR(Sample *sample)
void doInterpolateFIR(qint32 *x, qint32 *y)
void myInterpolateZeroStuffing(int32_t *x1, int32_t *y1, int32_t *x2, int32_t *y2)
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)
int32_t i
Definition: decimators.h:244
bool workInterpolateUpperHalf(Sample *sampleIn, Sample *sampleOut)
void setImag(FixReal v)
Definition: dsptypes.h:59
bool workInterpolateUpperHalfZeroStuffing(Sample *sampleIn, Sample *sampleOut)
bool workInterpolateCenter(Sample *sampleIn, Sample *SampleOut)
int int32_t
Definition: rtptypes_win.h:45
void myInterpolateSup(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2, qint32 *x3, qint32 *y3, qint32 *x4, qint32 *y4)
EOStorageType m_odd[2][HBFIRFilterTraits< HBFilterOrder >::hbOrder]
void myDecimateCen(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x3, int32_t y3, int32_t x4, int32_t y4, int32_t *out)
void setReal(FixReal v)
Definition: dsptypes.h:58
bool workDecimateCenter(Sample *sample)
void storeSample(const FixReal &sampleI, const FixReal &sampleQ)
FixReal real() const
Definition: dsptypes.h:61
FixReal imag() const
Definition: dsptypes.h:62
EOStorageType m_samples[HBFIRFilterTraits< HBFilterOrder >::hbOrder][2]
void doFIR(int32_t *x, int32_t *y)
void myDecimateInf(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x3, int32_t y3, int32_t x4, int32_t y4, int32_t *out)
EOStorageType m_even[2][HBFIRFilterTraits< HBFilterOrder >::hbOrder]
bool workDecimateUpperHalf(Sample *sample)
qint16 FixReal
Definition: dsptypes.h:35