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