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.
inthalfbandfiltereo2.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_INTHALFBANDFILTEREO2_H_
24 #define SDRBASE_DSP_INTHALFBANDFILTEREO2_H_
25 
26 #include <stdint.h>
27 #include <cstdlib>
28 #include "dsp/dsptypes.h"
29 #include "dsp/hbfiltertraits.h"
30 #include "export.h"
31 
32 template<uint32_t HBFilterOrder>
34 public:
36 
37  // downsample by 2, return center part of original spectrum
38  bool workDecimateCenter(Sample* sample)
39  {
40  // insert sample into ring-buffer
41  storeSample((FixReal) sample->real(), (FixReal) sample->imag());
42 
43  switch(m_state)
44  {
45  case 0:
46  // advance write-pointer
47  advancePointer();
48  // next state
49  m_state = 1;
50  // tell caller we don't have a new sample
51  return false;
52 
53  default:
54  // save result
55  doFIR(sample);
56  // advance write-pointer
57  advancePointer();
58  // next state
59  m_state = 0;
60 
61  // tell caller we have a new sample
62  return true;
63  }
64  }
65 
66  // upsample by 2, return center part of original spectrum - double buffer variant
67  bool workInterpolateCenterZeroStuffing(Sample* sampleIn, Sample *SampleOut)
68  {
69  switch(m_state)
70  {
71  case 0:
72  // insert sample into ring-buffer
73  storeSample((FixReal) 0, (FixReal) 0);
74  // save result
75  doFIR(SampleOut);
76  // advance write-pointer
77  advancePointer();
78  // next state
79  m_state = 1;
80  // tell caller we didn't consume the sample
81  return false;
82 
83  default:
84  // insert sample into ring-buffer
85  storeSample((FixReal) sampleIn->real(), (FixReal) sampleIn->imag());
86  // save result
87  doFIR(SampleOut);
88  // advance write-pointer
89  advancePointer();
90  // next state
91  m_state = 0;
92  // tell caller we consumed the sample
93  return true;
94  }
95  }
96 
98  bool workInterpolateCenter(Sample* sampleIn, Sample *SampleOut)
99  {
100  switch(m_state)
101  {
102  case 0:
103  // return the middle peak
104  SampleOut->setReal(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]);
105  SampleOut->setImag(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]);
106  m_state = 1; // next state
107  return false; // tell caller we didn't consume the sample
108 
109  default:
110  // calculate with non null samples
111  doInterpolateFIR(SampleOut);
112 
113  // insert sample into ring double buffer
114  m_samples[m_ptr][0] = sampleIn->real();
115  m_samples[m_ptr][1] = sampleIn->imag();
116  m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
117  m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
118 
119  // advance pointer
120  if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
121  m_ptr++;
122  } else {
123  m_ptr = 0;
124  }
125 
126  m_state = 0; // next state
127  return true; // tell caller we consumed the sample
128  }
129  }
130 
132  {
133  // insert sample into ring-buffer
134  storeSample32(*x, *y);
135 
136  switch(m_state)
137  {
138  case 0:
139  // advance write-pointer
140  advancePointer();
141  // next state
142  m_state = 1;
143  // tell caller we don't have a new sample
144  return false;
145 
146  default:
147  // save result
148  doFIR(x, y);
149  // advance write-pointer
150  advancePointer();
151  // next state
152  m_state = 0;
153  // tell caller we have a new sample
154  return true;
155  }
156  }
157 
158  // downsample by 2, return lower half of original spectrum
160  {
161  switch(m_state)
162  {
163  case 0:
164  // insert sample into ring-buffer
165  storeSample((FixReal) -sample->imag(), (FixReal) sample->real());
166  // advance write-pointer
167  advancePointer();
168  // next state
169  m_state = 1;
170  // tell caller we don't have a new sample
171  return false;
172 
173  case 1:
174  // insert sample into ring-buffer
175  storeSample((FixReal) -sample->real(), (FixReal) -sample->imag());
176  // save result
177  doFIR(sample);
178  // advance write-pointer
179  advancePointer();
180  // next state
181  m_state = 2;
182  // tell caller we have a new sample
183  return true;
184 
185  case 2:
186  // insert sample into ring-buffer
187  storeSample((FixReal) sample->imag(), (FixReal) -sample->real());
188  // advance write-pointer
189  advancePointer();
190  // next state
191  m_state = 3;
192  // tell caller we don't have a new sample
193  return false;
194 
195  default:
196  // insert sample into ring-buffer
197  storeSample((FixReal) sample->real(), (FixReal) sample->imag());
198  // save result
199  doFIR(sample);
200  // advance write-pointer
201  advancePointer();
202  // next state
203  m_state = 0;
204  // tell caller we have a new sample
205  return true;
206  }
207  }
208 
209  // upsample by 2, from lower half of original spectrum - double buffer variant
211  {
212  Sample s;
213 
214  switch(m_state)
215  {
216  case 0:
217  // insert sample into ring-buffer
218  storeSample((FixReal) 0, (FixReal) 0);
219 
220  // save result
221  doFIR(&s);
222  sampleOut->setReal(s.imag());
223  sampleOut->setImag(-s.real());
224 
225  // advance write-pointer
226  advancePointer();
227 
228  // next state
229  m_state = 1;
230 
231  // tell caller we didn't consume the sample
232  return false;
233 
234  case 1:
235  // insert sample into ring-buffer
236  storeSample((FixReal) sampleIn->real(), (FixReal) sampleIn->imag());
237 
238  // save result
239  doFIR(&s);
240  sampleOut->setReal(-s.real());
241  sampleOut->setImag(-s.imag());
242 
243  // advance write-pointer
244  advancePointer();
245 
246  // next state
247  m_state = 2;
248 
249  // tell caller we consumed the sample
250  return true;
251 
252  case 2:
253  // insert sample into ring-buffer
254  storeSample((FixReal) 0, (FixReal) 0);
255 
256  // save result
257  doFIR(&s);
258  sampleOut->setReal(-s.imag());
259  sampleOut->setImag(s.real());
260 
261  // advance write-pointer
262  advancePointer();
263 
264  // next state
265  m_state = 3;
266 
267  // tell caller we didn't consume the sample
268  return false;
269 
270  default:
271  // insert sample into ring-buffer
272  storeSample((FixReal) sampleIn->real(), (FixReal) sampleIn->imag());
273 
274  // save result
275  doFIR(&s);
276  sampleOut->setReal(s.real());
277  sampleOut->setImag(s.imag());
278 
279  // advance write-pointer
280  advancePointer();
281 
282  // next state
283  m_state = 0;
284 
285  // tell caller we consumed the sample
286  return true;
287  }
288  }
289 
291  bool workInterpolateLowerHalf(Sample* sampleIn, Sample *sampleOut)
292  {
293  Sample s;
294 
295  switch(m_state)
296  {
297  case 0:
298  // return the middle peak
299  sampleOut->setReal(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // imag
300  sampleOut->setImag(-m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // - real
301  m_state = 1; // next state
302  return false; // tell caller we didn't consume the sample
303 
304  case 1:
305  // calculate with non null samples
306  doInterpolateFIR(&s);
307  sampleOut->setReal(-s.real());
308  sampleOut->setImag(-s.imag());
309 
310  // insert sample into ring double buffer
311  m_samples[m_ptr][0] = sampleIn->real();
312  m_samples[m_ptr][1] = sampleIn->imag();
313  m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
314  m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
315 
316  // advance pointer
317  if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
318  m_ptr++;
319  } else {
320  m_ptr = 0;
321  }
322 
323  m_state = 2; // next state
324  return true; // tell caller we consumed the sample
325 
326  case 2:
327  // return the middle peak
328  sampleOut->setReal(-m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // - imag
329  sampleOut->setImag(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // real
330  m_state = 3; // next state
331  return false; // tell caller we didn't consume the sample
332 
333  default:
334  // calculate with non null samples
335  doInterpolateFIR(&s);
336  sampleOut->setReal(s.real());
337  sampleOut->setImag(s.imag());
338 
339  // insert sample into ring double buffer
340  m_samples[m_ptr][0] = sampleIn->real();
341  m_samples[m_ptr][1] = sampleIn->imag();
342  m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
343  m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
344 
345  // advance pointer
346  if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
347  m_ptr++;
348  } else {
349  m_ptr = 0;
350  }
351 
352  m_state = 0; // next state
353  return true; // tell caller we consumed the sample
354  }
355  }
356 
357  // downsample by 2, return upper half of original spectrum
359  {
360  switch(m_state)
361  {
362  case 0:
363  // insert sample into ring-buffer
364  storeSample((FixReal) sample->imag(), (FixReal) -sample->real());
365  // advance write-pointer
366  advancePointer();
367  // next state
368  m_state = 1;
369  // tell caller we don't have a new sample
370  return false;
371 
372  case 1:
373  // insert sample into ring-buffer
374  storeSample((FixReal) -sample->real(), (FixReal) -sample->imag());
375  // save result
376  doFIR(sample);
377  // advance write-pointer
378  advancePointer();
379  // next state
380  m_state = 2;
381  // tell caller we have a new sample
382  return true;
383 
384  case 2:
385  // insert sample into ring-buffer
386  storeSample((FixReal) -sample->imag(), (FixReal) sample->real());
387  // advance write-pointer
388  advancePointer();
389  // next state
390  m_state = 3;
391  // tell caller we don't have a new sample
392  return false;
393 
394  default:
395  // insert sample into ring-buffer
396  storeSample((FixReal) sample->real(), (FixReal) sample->imag());
397  // save result
398  doFIR(sample);
399  // advance write-pointer
400  advancePointer();
401  // next state
402  m_state = 0;
403  // tell caller we have a new sample
404  return true;
405  }
406  }
407 
408  // upsample by 2, move original spectrum to upper half - double buffer variant
410  {
411  Sample s;
412 
413  switch(m_state)
414  {
415  case 0:
416  // insert sample into ring-buffer
417  storeSample((FixReal) 0, (FixReal) 0);
418 
419  // save result
420  doFIR(&s);
421  sampleOut->setReal(-s.imag());
422  sampleOut->setImag(s.real());
423 
424  // advance write-pointer
425  advancePointer();
426 
427  // next state
428  m_state = 1;
429 
430  // tell caller we didn't consume the sample
431  return false;
432 
433  case 1:
434  // insert sample into ring-buffer
435  storeSample((FixReal) sampleIn->real(), (FixReal) sampleIn->imag());
436 
437  // save result
438  doFIR(&s);
439  sampleOut->setReal(-s.real());
440  sampleOut->setImag(-s.imag());
441 
442  // advance write-pointer
443  advancePointer();
444 
445  // next state
446  m_state = 2;
447 
448  // tell caller we consumed the sample
449  return true;
450 
451  case 2:
452  // insert sample into ring-buffer
453  storeSample((FixReal) 0, (FixReal) 0);
454 
455  // save result
456  doFIR(&s);
457  sampleOut->setReal(s.imag());
458  sampleOut->setImag(-s.real());
459 
460  // advance write-pointer
461  advancePointer();
462 
463  // next state
464  m_state = 3;
465 
466  // tell caller we didn't consume the sample
467  return false;
468 
469  default:
470  // insert sample into ring-buffer
471  storeSample((FixReal) sampleIn->real(), (FixReal) sampleIn->imag());
472 
473  // save result
474  doFIR(&s);
475  sampleOut->setReal(s.real());
476  sampleOut->setImag(s.imag());
477 
478  // advance write-pointer
479  advancePointer();
480 
481  // next state
482  m_state = 0;
483 
484  // tell caller we consumed the sample
485  return true;
486  }
487  }
488 
490  bool workInterpolateUpperHalf(Sample* sampleIn, Sample *sampleOut)
491  {
492  Sample s;
493 
494  switch(m_state)
495  {
496  case 0:
497  // return the middle peak
498  sampleOut->setReal(-m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // - imag
499  sampleOut->setImag(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // + real
500  m_state = 1; // next state
501  return false; // tell caller we didn't consume the sample
502 
503  case 1:
504  // calculate with non null samples
505  doInterpolateFIR(&s);
506  sampleOut->setReal(-s.real());
507  sampleOut->setImag(-s.imag());
508 
509  // insert sample into ring double buffer
510  m_samples[m_ptr][0] = sampleIn->real();
511  m_samples[m_ptr][1] = sampleIn->imag();
512  m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
513  m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
514 
515  // advance pointer
516  if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
517  m_ptr++;
518  } else {
519  m_ptr = 0;
520  }
521 
522  m_state = 2; // next state
523  return true; // tell caller we consumed the sample
524 
525  case 2:
526  // return the middle peak
527  sampleOut->setReal(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // + imag
528  sampleOut->setImag(-m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // - real
529  m_state = 3; // next state
530  return false; // tell caller we didn't consume the sample
531 
532  default:
533  // calculate with non null samples
534  doInterpolateFIR(&s);
535  sampleOut->setReal(s.real());
536  sampleOut->setImag(s.imag());
537 
538  // insert sample into ring double buffer
539  m_samples[m_ptr][0] = sampleIn->real();
540  m_samples[m_ptr][1] = sampleIn->imag();
541  m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
542  m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
543 
544  // advance pointer
545  if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
546  m_ptr++;
547  } else {
548  m_ptr = 0;
549  }
550 
551  m_state = 0; // next state
552  return true; // tell caller we consumed the sample
553  }
554  }
555 
556  void myDecimate(const Sample* sample1, Sample* sample2)
557  {
558  storeSample((FixReal) sample1->real(), (FixReal) sample1->imag());
559  advancePointer();
560 
561  storeSample((FixReal) sample2->real(), (FixReal) sample2->imag());
562  doFIR(sample2);
563  advancePointer();
564  }
565 
566  void myDecimate(int32_t x1, int32_t y1, int32_t *x2, int32_t *y2)
567  {
568  storeSample32(x1, y1);
569  advancePointer();
570 
571  storeSample32(*x2, *y2);
572  doFIR(x2, y2);
573  advancePointer();
574  }
575 
577  void myInterpolateZeroStuffing(Sample* sample1, Sample* sample2)
578  {
579  storeSample((FixReal) sample1->real(), (FixReal) sample1->imag());
580  doFIR(sample1);
581  advancePointer();
582 
583  storeSample((FixReal) 0, (FixReal) 0);
584  doFIR(sample2);
585  advancePointer();
586  }
587 
590  {
591  storeSample32(*x1, *y1);
592  doFIR(x1, y1);
593  advancePointer();
594 
595  storeSample32(0, 0);
596  doFIR(x2, y2);
597  advancePointer();
598  }
599 
601  void myInterpolate(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2)
602  {
603  // insert sample into ring double buffer
604  m_samples[m_ptr][0] = *x1;
605  m_samples[m_ptr][1] = *y1;
606  m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = *x1;
607  m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = *y1;
608 
609  // advance pointer
610  if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
611  m_ptr++;
612  } else {
613  m_ptr = 0;
614  }
615 
616  // first output sample calculated with the middle peak
617  *x1 = m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0];
618  *y1 = m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1];
619 
620  // second sample calculated with the filter
621  doInterpolateFIR(x2, y2);
622  }
623 
624  void myInterpolateInf(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2, qint32 *x3, qint32 *y3, qint32 *x4, qint32 *y4)
625  {
626  myInterpolate(x1, y1, x2, y2);
627  myInterpolate(x3, y3, x4, y4);
628  // rotation
629  qint32 x;
630  x = *x1;
631  *x1 = *y1;
632  *y1 = -x;
633  *x2 = -*x2;
634  *y2 = -*y2;
635  x = *x3;
636  *x3 = -*y3;
637  *y3 = x;
638  }
639 
640  void myInterpolateSup(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2, qint32 *x3, qint32 *y3, qint32 *x4, qint32 *y4)
641  {
642  myInterpolate(x1, y1, x2, y2);
643  myInterpolate(x3, y3, x4, y4);
644  // rotation
645  qint32 x;
646  x = *x1;
647  *x1 = -*y1;
648  *y1 = x;
649  *x2 = -*x2;
650  *y2 = -*y2;
651  x = *x3;
652  *x3 = *y3;
653  *y3 = -x;
654  }
655 
656 protected:
657  qint64 m_even[2][HBFIRFilterTraits<HBFilterOrder>::hbOrder]; // double buffer technique
658  qint64 m_odd[2][HBFIRFilterTraits<HBFilterOrder>::hbOrder]; // double buffer technique
659  int32_t m_samples[HBFIRFilterTraits<HBFilterOrder>::hbOrder][2]; // double buffer technique
660 
661  int m_ptr;
662  int m_size;
663  int m_state;
664 
665  void storeSample(const FixReal& sampleI, const FixReal& sampleQ)
666  {
667  if ((m_ptr % 2) == 0)
668  {
669  m_even[0][m_ptr/2] = sampleI;
670  m_even[1][m_ptr/2] = sampleQ;
671  m_even[0][m_ptr/2 + m_size] = sampleI;
672  m_even[1][m_ptr/2 + m_size] = sampleQ;
673  }
674  else
675  {
676  m_odd[0][m_ptr/2] = sampleI;
677  m_odd[1][m_ptr/2] = sampleQ;
678  m_odd[0][m_ptr/2 + m_size] = sampleI;
679  m_odd[1][m_ptr/2 + m_size] = sampleQ;
680  }
681  }
682 
684  {
685  if ((m_ptr % 2) == 0)
686  {
687  m_even[0][m_ptr/2] = x;
688  m_even[1][m_ptr/2] = y;
689  m_even[0][m_ptr/2 + m_size] = x;
690  m_even[1][m_ptr/2 + m_size] = y;
691  }
692  else
693  {
694  m_odd[0][m_ptr/2] = x;
695  m_odd[1][m_ptr/2] = y;
696  m_odd[0][m_ptr/2 + m_size] = x;
697  m_odd[1][m_ptr/2 + m_size] = y;
698  }
699  }
700 
701  void storeSample64(qint64 x, qint64 y)
702  {
703  if ((m_ptr % 2) == 0)
704  {
705  m_even[0][m_ptr/2] = x;
706  m_even[1][m_ptr/2] = y;
707  m_even[0][m_ptr/2 + m_size] = x;
708  m_even[1][m_ptr/2 + m_size] = y;
709  }
710  else
711  {
712  m_odd[0][m_ptr/2] = x;
713  m_odd[1][m_ptr/2] = y;
714  m_odd[0][m_ptr/2 + m_size] = x;
715  m_odd[1][m_ptr/2 + m_size] = y;
716  }
717  }
718 
720  {
721  m_ptr = m_ptr + 1 < 2*m_size ? m_ptr + 1: 0;
722  }
723 
724  void doFIR(Sample* sample)
725  {
726  qint64 iAcc = 0;
727  qint64 qAcc = 0;
728 
729  int a = m_ptr/2 + m_size; // tip pointer
730  int b = m_ptr/2 + 1; // tail pointer
731  for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder / 4; i++)
732  {
733  if ((m_ptr % 2) == 0)
734  {
735  iAcc += (m_even[0][a] + m_even[0][b]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
736  qAcc += (m_even[1][a] + m_even[1][b]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
737  }
738  else
739  {
740  iAcc += (m_odd[0][a] + m_odd[0][b]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
741  qAcc += (m_odd[1][a] + m_odd[1][b]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
742  }
743 
744  a -= 1;
745  b += 1;
746  }
747 
748  if ((m_ptr % 2) == 0)
749  {
750  iAcc += ((int32_t)m_odd[0][m_ptr/2 + m_size/2]) << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
751  qAcc += ((int32_t)m_odd[1][m_ptr/2 + m_size/2]) << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
752  }
753  else
754  {
755  iAcc += ((int32_t)m_even[0][m_ptr/2 + m_size/2 + 1]) << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
756  qAcc += ((int32_t)m_even[1][m_ptr/2 + m_size/2 + 1]) << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
757  }
758 
761  }
762 
763  void doFIR(int32_t *x, int32_t *y)
764  {
765  qint64 iAcc = 0;
766  qint64 qAcc = 0;
767 
768  int a = m_ptr/2 + m_size; // tip pointer
769  int b = m_ptr/2 + 1; // tail pointer
770 
771  for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder / 4; i++)
772  {
773  if ((m_ptr % 2) == 0)
774  {
775  iAcc += (m_even[0][a] + m_even[0][b]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
776  qAcc += (m_even[1][a] + m_even[1][b]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
777  }
778  else
779  {
780  iAcc += (m_odd[0][a] + m_odd[0][b]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
781  qAcc += (m_odd[1][a] + m_odd[1][b]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
782  }
783 
784  a -= 1;
785  b += 1;
786  }
787 
788  if ((m_ptr % 2) == 0)
789  {
790  iAcc += ((int32_t)m_odd[0][m_ptr/2 + m_size/2]) << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
791  qAcc += ((int32_t)m_odd[1][m_ptr/2 + m_size/2]) << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
792  }
793  else
794  {
795  iAcc += ((int32_t)m_even[0][m_ptr/2 + m_size/2 + 1]) << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
796  qAcc += ((int32_t)m_even[1][m_ptr/2 + m_size/2 + 1]) << (HBFIRFilterTraits<HBFilterOrder>::hbShift - 1);
797  }
798 
799  *x = iAcc >> (HBFIRFilterTraits<HBFilterOrder>::hbShift -1); // HB_SHIFT incorrect do not loose the gained bit
801  }
802 
803  void doInterpolateFIR(Sample* sample)
804  {
805  qint64 iAcc = 0;
806  qint64 qAcc = 0;
807 
808  qint16 a = m_ptr;
809  qint16 b = m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder / 2) - 1;
810 
811  // go through samples in buffer
812  for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder / 4; i++)
813  {
814  iAcc += (m_samples[a][0] + m_samples[b][0]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
815  qAcc += (m_samples[a][1] + m_samples[b][1]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
816  a++;
817  b--;
818  }
819 
822  }
823 
824  void doInterpolateFIR(qint32 *x, qint32 *y)
825  {
826  qint64 iAcc = 0;
827  qint64 qAcc = 0;
828 
829  qint16 a = m_ptr;
830  qint16 b = m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder / 2) - 1;
831 
832  // go through samples in buffer
833  for (int i = 0; i < HBFIRFilterTraits<HBFilterOrder>::hbOrder / 4; i++)
834  {
835  iAcc += (m_samples[a][0] + m_samples[b][0]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
836  qAcc += (m_samples[a][1] + m_samples[b][1]) * HBFIRFilterTraits<HBFilterOrder>::hbCoeffs[i];
837  a++;
838  b--;
839  }
840 
843  }
844 };
845 
846 template<uint32_t HBFilterOrder>
848 {
850 
851  for (int i = 0; i < 2*m_size; i++)
852  {
853  m_even[0][i] = 0;
854  m_even[1][i] = 0;
855  m_odd[0][i] = 0;
856  m_odd[1][i] = 0;
857  m_samples[i][0] = 0;
858  m_samples[i][1] = 0;
859  }
860 
861  m_ptr = 0;
862  m_state = 0;
863 }
864 
865 #endif /* SDRBASE_DSP_INTHALFBANDFILTEREO2_H_ */
void storeSample(const FixReal &sampleI, const FixReal &sampleQ)
void myInterpolate(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2)
void myDecimate(int32_t x1, int32_t y1, int32_t *x2, int32_t *y2)
void storeSample64(qint64 x, qint64 y)
void doFIR(int32_t *x, int32_t *y)
void myInterpolateInf(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2, qint32 *x3, qint32 *y3, qint32 *x4, qint32 *y4)
void doInterpolateFIR(qint32 *x, qint32 *y)
bool workDecimateLowerHalf(Sample *sample)
void doFIR(Sample *sample)
bool workInterpolateUpperHalfZeroStuffing(Sample *sampleIn, Sample *sampleOut)
void doInterpolateFIR(Sample *sample)
void myDecimate(const Sample *sample1, Sample *sample2)
bool workInterpolateLowerHalfZeroStuffing(Sample *sampleIn, Sample *sampleOut)
bool workInterpolateLowerHalf(Sample *sampleIn, Sample *sampleOut)
bool workDecimateUpperHalf(Sample *sample)
bool workDecimateCenter(Sample *sample)
bool workDecimateCenter(int32_t *x, int32_t *y)
int32_t i
Definition: decimators.h:244
void setImag(FixReal v)
Definition: dsptypes.h:59
int int32_t
Definition: rtptypes_win.h:45
void myInterpolateZeroStuffing(int32_t *x1, int32_t *y1, int32_t *x2, int32_t *y2)
void myInterpolateZeroStuffing(Sample *sample1, Sample *sample2)
bool workInterpolateCenterZeroStuffing(Sample *sampleIn, Sample *SampleOut)
bool workInterpolateUpperHalf(Sample *sampleIn, Sample *sampleOut)
void myInterpolateSup(qint32 *x1, qint32 *y1, qint32 *x2, qint32 *y2, qint32 *x3, qint32 *y3, qint32 *x4, qint32 *y4)
void storeSample32(int32_t x, int32_t y)
void setReal(FixReal v)
Definition: dsptypes.h:58
FixReal real() const
Definition: dsptypes.h:61
FixReal imag() const
Definition: dsptypes.h:62
bool workInterpolateCenter(Sample *sampleIn, Sample *SampleOut)
#define SDRBASE_API
Definition: export.h:40
qint16 FixReal
Definition: dsptypes.h:35