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.
soapysdrinputthread.cpp
Go to the documentation of this file.
1 // Copyright (C) 2018 Edouard Griffiths, F4EXB //
3 // //
4 // This program is free software; you can redistribute it and/or modify //
5 // it under the terms of the GNU General Public License as published by //
6 // the Free Software Foundation as version 3 of the License, or //
7 // (at your option) any later version. //
8 // //
9 // This program is distributed in the hope that it will be useful, //
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
12 // GNU General Public License V3 for more details. //
13 // //
14 // You should have received a copy of the GNU General Public License //
15 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
17 
18 #include <vector>
19 #include <algorithm>
20 
21 #include <SoapySDR/Formats.hpp>
22 #include <SoapySDR/Errors.hpp>
23 
24 #include "dsp/samplesinkfifo.h"
26 
27 #include "soapysdrinputthread.h"
28 
29 SoapySDRInputThread::SoapySDRInputThread(SoapySDR::Device* dev, unsigned int nbRxChannels, QObject* parent) :
30  QThread(parent),
31  m_running(false),
32  m_dev(dev),
33  m_sampleRate(0),
34  m_nbChannels(nbRxChannels),
35  m_decimatorType(DecimatorFloat)
36 {
37  qDebug("SoapySDRInputThread::SoapySDRInputThread");
38  m_channels = new Channel[nbRxChannels];
39 }
40 
42 {
43  qDebug("SoapySDRInputThread::~SoapySDRInputThread");
44 
45  if (m_running) {
46  stopWork();
47  }
48 
49  delete[] m_channels;
50 }
51 
53 {
54  if (m_running) {
55  return;
56  }
57 
58  m_startWaitMutex.lock();
59  start();
60 
61  while(!m_running) {
62  m_startWaiter.wait(&m_startWaitMutex, 100);
63  }
64 
65  m_startWaitMutex.unlock();
66 }
67 
69 {
70  if (!m_running) {
71  return;
72  }
73 
74  m_running = false;
75  wait();
76 }
77 
79 {
80  m_running = true;
81  m_startWaiter.wakeAll();
82 
83  unsigned int nbFifos = getNbFifos();
84 
85  if ((m_nbChannels > 0) && (nbFifos > 0))
86  {
87  // build channels list
88  std::vector<std::size_t> channels(m_nbChannels);
89  std::iota(channels.begin(), channels.end(), 0); // Fill with 0, 1, ..., m_nbChannels-1.
90 
91  //initialize the sample rate for all channels
92  for (const auto &it : channels) {
93  m_dev->setSampleRate(SOAPY_SDR_RX, it, m_sampleRate);
94  }
95 
96  // Determine sample format to be used
97  double fullScale(0.0);
98  std::string format = m_dev->getNativeStreamFormat(SOAPY_SDR_RX, channels.front(), fullScale);
99 
100  qDebug("SoapySDRInputThread::run: format: %s fullScale: %f", format.c_str(), fullScale);
101 
102  if ((format == "CS8") && (fullScale == 128.0)) { // 8 bit signed - native
104  } else if ((format == "CS16") && (fullScale == 2048.0)) { // 12 bit signed - native
106  } else if ((format == "CS16") && (fullScale == 32768.0)) { // 16 bit signed - native
108  } else { // for other types make a conversion to float
110  format = "CF32";
111  }
112 
113  unsigned int elemSize = SoapySDR::formatToSize(format); // sample (I+Q) size in bytes
114  SoapySDR::Stream *stream = m_dev->setupStream(SOAPY_SDR_RX, format, channels);
115 
116  //allocate buffers for the stream read/write
117  const unsigned int numElems = m_dev->getStreamMTU(stream); // number of samples (I+Q)
118  std::vector<std::vector<char>> buffMem(m_nbChannels, std::vector<char>(elemSize*numElems));
119  std::vector<void *> buffs(m_nbChannels);
120 
121  for (std::size_t i = 0; i < m_nbChannels; i++) {
122  buffs[i] = buffMem[i].data();
123  }
124 
125  for (unsigned int i = 0; i < m_nbChannels; i++) {
126  m_channels[i].m_convertBuffer.resize(numElems, Sample{0,0});
127  }
128 
129  m_dev->activateStream(stream);
130  int flags(0);
131  long long timeNs(0);
132  float blockTime = ((float) numElems) / (m_sampleRate <= 0 ? 1024000 : m_sampleRate);
133  long initialTtimeoutUs = 10000000 * blockTime; // 10 times the block time
134  long timeoutUs = initialTtimeoutUs < 250000 ? 250000 : initialTtimeoutUs; // 250ms minimum
135 
136  qDebug("SoapySDRInputThread::run: numElems: %u elemSize: %u initialTtimeoutUs: %ld timeoutUs: %ld",
137  numElems, elemSize, initialTtimeoutUs, timeoutUs);
138  qDebug("SoapySDRInputThread::run: start running loop");
139 
140  while (m_running)
141  {
142  int ret = m_dev->readStream(stream, buffs.data(), numElems, flags, timeNs, timeoutUs);
143 
144  if (ret == SOAPY_SDR_TIMEOUT)
145  {
146  qWarning("SoapySDRInputThread::run: timeout: flags: %d timeNs: %lld timeoutUs: %ld", flags, timeNs, timeoutUs);
147  }
148  else if (ret == SOAPY_SDR_OVERFLOW)
149  {
150  qWarning("SoapySDRInputThread::run: overflow: flags: %d timeNs: %lld timeoutUs: %ld", flags, timeNs, timeoutUs);
151  }
152  else if (ret < 0)
153  {
154  qCritical("SoapySDRInputThread::run: Unexpected read stream error: %s", SoapySDR::errToStr(ret));
155  break;
156  }
157 
158  if (m_nbChannels > 1)
159  {
160  callbackMI(buffs, numElems*2); // size given in number of I or Q samples (2 items per sample)
161  }
162  else
163  {
164  switch (m_decimatorType)
165  {
166  case Decimator8:
167  callbackSI8((const qint8*) buffs[0], numElems*2);
168  break;
169  case Decimator12:
170  callbackSI12((const qint16*) buffs[0], numElems*2);
171  break;
172  case Decimator16:
173  callbackSI16((const qint16*) buffs[0], numElems*2);
174  break;
175  case DecimatorFloat:
176  default:
177  callbackSIF((const float*) buffs[0], numElems*2);
178  }
179  }
180  }
181 
182  qDebug("SoapySDRInputThread::run: stop running loop");
183  m_dev->deactivateStream(stream);
184  m_dev->closeStream(stream);
185  }
186  else
187  {
188  qWarning("SoapySDRInputThread::run: no channels or FIFO allocated. Aborting");
189  }
190 
191  m_running = false;
192 }
193 
195 {
196  unsigned int fifoCount = 0;
197 
198  for (unsigned int i = 0; i < m_nbChannels; i++)
199  {
200  if (m_channels[i].m_sampleFifo) {
201  fifoCount++;
202  }
203  }
204 
205  return fifoCount;
206 }
207 
208 void SoapySDRInputThread::setLog2Decimation(unsigned int channel, unsigned int log2_decim)
209 {
210  if (channel < m_nbChannels) {
211  m_channels[channel].m_log2Decim = log2_decim;
212  }
213 }
214 
215 unsigned int SoapySDRInputThread::getLog2Decimation(unsigned int channel) const
216 {
217  if (channel < m_nbChannels) {
218  return m_channels[channel].m_log2Decim;
219  } else {
220  return 0;
221  }
222 }
223 
224 void SoapySDRInputThread::setFcPos(unsigned int channel, int fcPos)
225 {
226  if (channel < m_nbChannels) {
227  m_channels[channel].m_fcPos = fcPos;
228  }
229 }
230 
231 int SoapySDRInputThread::getFcPos(unsigned int channel) const
232 {
233  if (channel < m_nbChannels) {
234  return m_channels[channel].m_fcPos;
235  } else {
236  return 0;
237  }
238 }
239 
240 void SoapySDRInputThread::setFifo(unsigned int channel, SampleSinkFifo *sampleFifo)
241 {
242  if (channel < m_nbChannels) {
243  m_channels[channel].m_sampleFifo = sampleFifo;
244  }
245 }
246 
248 {
249  if (channel < m_nbChannels) {
250  return m_channels[channel].m_sampleFifo;
251  } else {
252  return 0;
253  }
254 }
255 
256 void SoapySDRInputThread::callbackMI(std::vector<void *>& buffs, qint32 samplesPerChannel)
257 {
258  for(unsigned int ichan = 0; ichan < m_nbChannels; ichan++)
259  {
260  switch (m_decimatorType)
261  {
262  case Decimator8:
263  callbackSI8((const qint8*) buffs[ichan], samplesPerChannel, ichan);
264  break;
265  case Decimator12:
266  callbackSI12((const qint16*) buffs[ichan], samplesPerChannel, ichan);
267  break;
268  case Decimator16:
269  callbackSI16((const qint16*) buffs[ichan], samplesPerChannel, ichan);
270  break;
271  case DecimatorFloat:
272  default:
273  callbackSIF((const float*) buffs[ichan], samplesPerChannel, ichan);
274  }
275  }
276 }
277 
278 void SoapySDRInputThread::callbackSI8(const qint8* buf, qint32 len, unsigned int channel)
279 {
280  SampleVector::iterator it = m_channels[channel].m_convertBuffer.begin();
281 
282  if (m_channels[channel].m_log2Decim == 0)
283  {
284  m_channels[channel].m_decimators8.decimate1(&it, buf, len);
285  }
286  else
287  {
288  if (m_channels[channel].m_fcPos == 0) // Infra
289  {
290  switch (m_channels[channel].m_log2Decim)
291  {
292  case 1:
293  m_channels[channel].m_decimators8.decimate2_inf(&it, buf, len);
294  break;
295  case 2:
296  m_channels[channel].m_decimators8.decimate4_inf(&it, buf, len);
297  break;
298  case 3:
299  m_channels[channel].m_decimators8.decimate8_inf(&it, buf, len);
300  break;
301  case 4:
302  m_channels[channel].m_decimators8.decimate16_inf(&it, buf, len);
303  break;
304  case 5:
305  m_channels[channel].m_decimators8.decimate32_inf(&it, buf, len);
306  break;
307  case 6:
308  m_channels[channel].m_decimators8.decimate64_inf(&it, buf, len);
309  break;
310  default:
311  break;
312  }
313  }
314  else if (m_channels[channel].m_fcPos == 1) // Supra
315  {
316  switch (m_channels[channel].m_log2Decim)
317  {
318  case 1:
319  m_channels[channel].m_decimators8.decimate2_sup(&it, buf, len);
320  break;
321  case 2:
322  m_channels[channel].m_decimators8.decimate4_sup(&it, buf, len);
323  break;
324  case 3:
325  m_channels[channel].m_decimators8.decimate8_sup(&it, buf, len);
326  break;
327  case 4:
328  m_channels[channel].m_decimators8.decimate16_sup(&it, buf, len);
329  break;
330  case 5:
331  m_channels[channel].m_decimators8.decimate32_sup(&it, buf, len);
332  break;
333  case 6:
334  m_channels[channel].m_decimators8.decimate64_sup(&it, buf, len);
335  break;
336  default:
337  break;
338  }
339  }
340  else if (m_channels[channel].m_fcPos == 2) // Center
341  {
342  switch (m_channels[channel].m_log2Decim)
343  {
344  case 1:
345  m_channels[channel].m_decimators8.decimate2_cen(&it, buf, len);
346  break;
347  case 2:
348  m_channels[channel].m_decimators8.decimate4_cen(&it, buf, len);
349  break;
350  case 3:
351  m_channels[channel].m_decimators8.decimate8_cen(&it, buf, len);
352  break;
353  case 4:
354  m_channels[channel].m_decimators8.decimate16_cen(&it, buf, len);
355  break;
356  case 5:
357  m_channels[channel].m_decimators8.decimate32_cen(&it, buf, len);
358  break;
359  case 6:
360  m_channels[channel].m_decimators8.decimate64_cen(&it, buf, len);
361  break;
362  default:
363  break;
364  }
365  }
366  }
367 
368  m_channels[channel].m_sampleFifo->write(m_channels[channel].m_convertBuffer.begin(), it);
369 }
370 
371 void SoapySDRInputThread::callbackSI12(const qint16* buf, qint32 len, unsigned int channel)
372 {
373  SampleVector::iterator it = m_channels[channel].m_convertBuffer.begin();
374 
375  if (m_channels[channel].m_log2Decim == 0)
376  {
377  m_channels[channel].m_decimators12.decimate1(&it, buf, len);
378  }
379  else
380  {
381  if (m_channels[channel].m_fcPos == 0) // Infra
382  {
383  switch (m_channels[channel].m_log2Decim)
384  {
385  case 1:
386  m_channels[channel].m_decimators12.decimate2_inf(&it, buf, len);
387  break;
388  case 2:
389  m_channels[channel].m_decimators12.decimate4_inf(&it, buf, len);
390  break;
391  case 3:
392  m_channels[channel].m_decimators12.decimate8_inf(&it, buf, len);
393  break;
394  case 4:
395  m_channels[channel].m_decimators12.decimate16_inf(&it, buf, len);
396  break;
397  case 5:
398  m_channels[channel].m_decimators12.decimate32_inf(&it, buf, len);
399  break;
400  case 6:
401  m_channels[channel].m_decimators12.decimate64_inf(&it, buf, len);
402  break;
403  default:
404  break;
405  }
406  }
407  else if (m_channels[channel].m_fcPos == 1) // Supra
408  {
409  switch (m_channels[channel].m_log2Decim)
410  {
411  case 1:
412  m_channels[channel].m_decimators12.decimate2_sup(&it, buf, len);
413  break;
414  case 2:
415  m_channels[channel].m_decimators12.decimate4_sup(&it, buf, len);
416  break;
417  case 3:
418  m_channels[channel].m_decimators12.decimate8_sup(&it, buf, len);
419  break;
420  case 4:
421  m_channels[channel].m_decimators12.decimate16_sup(&it, buf, len);
422  break;
423  case 5:
424  m_channels[channel].m_decimators12.decimate32_sup(&it, buf, len);
425  break;
426  case 6:
427  m_channels[channel].m_decimators12.decimate64_sup(&it, buf, len);
428  break;
429  default:
430  break;
431  }
432  }
433  else if (m_channels[channel].m_fcPos == 2) // Center
434  {
435  switch (m_channels[channel].m_log2Decim)
436  {
437  case 1:
438  m_channels[channel].m_decimators12.decimate2_cen(&it, buf, len);
439  break;
440  case 2:
441  m_channels[channel].m_decimators12.decimate4_cen(&it, buf, len);
442  break;
443  case 3:
444  m_channels[channel].m_decimators12.decimate8_cen(&it, buf, len);
445  break;
446  case 4:
447  m_channels[channel].m_decimators12.decimate16_cen(&it, buf, len);
448  break;
449  case 5:
450  m_channels[channel].m_decimators12.decimate32_cen(&it, buf, len);
451  break;
452  case 6:
453  m_channels[channel].m_decimators12.decimate64_cen(&it, buf, len);
454  break;
455  default:
456  break;
457  }
458  }
459  }
460 
461  m_channels[channel].m_sampleFifo->write(m_channels[channel].m_convertBuffer.begin(), it);
462 }
463 
464 void SoapySDRInputThread::callbackSI16(const qint16* buf, qint32 len, unsigned int channel)
465 {
466  SampleVector::iterator it = m_channels[channel].m_convertBuffer.begin();
467 
468  if (m_channels[channel].m_log2Decim == 0)
469  {
470  m_channels[channel].m_decimators16.decimate1(&it, buf, len);
471  }
472  else
473  {
474  if (m_channels[channel].m_fcPos == 0) // Infra
475  {
476  switch (m_channels[channel].m_log2Decim)
477  {
478  case 1:
479  m_channels[channel].m_decimators16.decimate2_inf(&it, buf, len);
480  break;
481  case 2:
482  m_channels[channel].m_decimators16.decimate4_inf(&it, buf, len);
483  break;
484  case 3:
485  m_channels[channel].m_decimators16.decimate8_inf(&it, buf, len);
486  break;
487  case 4:
488  m_channels[channel].m_decimators16.decimate16_inf(&it, buf, len);
489  break;
490  case 5:
491  m_channels[channel].m_decimators16.decimate32_inf(&it, buf, len);
492  break;
493  case 6:
494  m_channels[channel].m_decimators16.decimate64_inf(&it, buf, len);
495  break;
496  default:
497  break;
498  }
499  }
500  else if (m_channels[channel].m_fcPos == 1) // Supra
501  {
502  switch (m_channels[channel].m_log2Decim)
503  {
504  case 1:
505  m_channels[channel].m_decimators16.decimate2_sup(&it, buf, len);
506  break;
507  case 2:
508  m_channels[channel].m_decimators16.decimate4_sup(&it, buf, len);
509  break;
510  case 3:
511  m_channels[channel].m_decimators16.decimate8_sup(&it, buf, len);
512  break;
513  case 4:
514  m_channels[channel].m_decimators16.decimate16_sup(&it, buf, len);
515  break;
516  case 5:
517  m_channels[channel].m_decimators16.decimate32_sup(&it, buf, len);
518  break;
519  case 6:
520  m_channels[channel].m_decimators16.decimate64_sup(&it, buf, len);
521  break;
522  default:
523  break;
524  }
525  }
526  else if (m_channels[channel].m_fcPos == 2) // Center
527  {
528  switch (m_channels[channel].m_log2Decim)
529  {
530  case 1:
531  m_channels[channel].m_decimators16.decimate2_cen(&it, buf, len);
532  break;
533  case 2:
534  m_channels[channel].m_decimators16.decimate4_cen(&it, buf, len);
535  break;
536  case 3:
537  m_channels[channel].m_decimators16.decimate8_cen(&it, buf, len);
538  break;
539  case 4:
540  m_channels[channel].m_decimators16.decimate16_cen(&it, buf, len);
541  break;
542  case 5:
543  m_channels[channel].m_decimators16.decimate32_cen(&it, buf, len);
544  break;
545  case 6:
546  m_channels[channel].m_decimators16.decimate64_cen(&it, buf, len);
547  break;
548  default:
549  break;
550  }
551  }
552  }
553 
554  m_channels[channel].m_sampleFifo->write(m_channels[channel].m_convertBuffer.begin(), it);
555 }
556 
557 void SoapySDRInputThread::callbackSIF(const float* buf, qint32 len, unsigned int channel)
558 {
559  SampleVector::iterator it = m_channels[channel].m_convertBuffer.begin();
560 
561  if (m_channels[channel].m_log2Decim == 0)
562  {
563  m_channels[channel].m_decimatorsFloat.decimate1(&it, buf, len);
564  }
565  else
566  {
567  if (m_channels[channel].m_fcPos == 0) // Infra
568  {
569  switch (m_channels[channel].m_log2Decim)
570  {
571  case 1:
572  m_channels[channel].m_decimatorsFloat.decimate2_inf(&it, buf, len);
573  break;
574  case 2:
575  m_channels[channel].m_decimatorsFloat.decimate4_inf(&it, buf, len);
576  break;
577  case 3:
578  m_channels[channel].m_decimatorsFloat.decimate8_inf(&it, buf, len);
579  break;
580  case 4:
581  m_channels[channel].m_decimatorsFloat.decimate16_inf(&it, buf, len);
582  break;
583  case 5:
584  m_channels[channel].m_decimatorsFloat.decimate32_inf(&it, buf, len);
585  break;
586  case 6:
587  m_channels[channel].m_decimatorsFloat.decimate64_inf(&it, buf, len);
588  break;
589  default:
590  break;
591  }
592  }
593  else if (m_channels[channel].m_fcPos == 1) // Supra
594  {
595  switch (m_channels[channel].m_log2Decim)
596  {
597  case 1:
598  m_channels[channel].m_decimatorsFloat.decimate2_sup(&it, buf, len);
599  break;
600  case 2:
601  m_channels[channel].m_decimatorsFloat.decimate4_sup(&it, buf, len);
602  break;
603  case 3:
604  m_channels[channel].m_decimatorsFloat.decimate8_sup(&it, buf, len);
605  break;
606  case 4:
607  m_channels[channel].m_decimatorsFloat.decimate16_sup(&it, buf, len);
608  break;
609  case 5:
610  m_channels[channel].m_decimatorsFloat.decimate32_sup(&it, buf, len);
611  break;
612  case 6:
613  m_channels[channel].m_decimatorsFloat.decimate64_sup(&it, buf, len);
614  break;
615  default:
616  break;
617  }
618  }
619  else if (m_channels[channel].m_fcPos == 2) // Center
620  {
621  switch (m_channels[channel].m_log2Decim)
622  {
623  case 1:
624  m_channels[channel].m_decimatorsFloat.decimate2_cen(&it, buf, len);
625  break;
626  case 2:
627  m_channels[channel].m_decimatorsFloat.decimate4_cen(&it, buf, len);
628  break;
629  case 3:
630  m_channels[channel].m_decimatorsFloat.decimate8_cen(&it, buf, len);
631  break;
632  case 4:
633  m_channels[channel].m_decimatorsFloat.decimate16_cen(&it, buf, len);
634  break;
635  case 5:
636  m_channels[channel].m_decimatorsFloat.decimate32_cen(&it, buf, len);
637  break;
638  case 6:
639  m_channels[channel].m_decimatorsFloat.decimate64_cen(&it, buf, len);
640  break;
641  default:
642  break;
643  }
644  }
645  }
646 
647  m_channels[channel].m_sampleFifo->write(m_channels[channel].m_convertBuffer.begin(), it);
648 }
void decimate32_inf(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
void decimate8_inf(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
void decimate8_sup(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
void decimate2_inf(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:498
void decimate4_inf(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
void decimate64_sup(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:2975
void decimate32_cen(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
void decimate32_sup(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
void decimate64_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:3040
void decimate2_sup(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:526
void decimate2_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:554
uint write(const quint8 *data, uint count)
DecimatorType m_decimatorType
Channel * m_channels
Array of channels dynamically allocated for the given number of Rx channels.
Decimators< qint32, qint8, SDR_RX_SAMP_SZ, 8 > m_decimators8
void decimate8_sup(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:941
void callbackMI(std::vector< void *> &buffs, qint32 samplesPerChannel)
void decimate4_sup(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
void setFcPos(unsigned int channel, int fcPos)
void callbackSI12(const qint16 *buf, qint32 len, unsigned int channel=0)
void callbackSI8(const qint8 *buf, qint32 len, unsigned int channel=0)
void decimate64_inf(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:2418
void decimate64_sup(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
void decimate32_inf(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1592
void decimate32_sup(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1902
QWaitCondition m_startWaiter
int getFcPos(unsigned int channel) const
void decimate4_sup(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:682
SoapySDR::Device * m_dev
void decimate8_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1057
void decimate16_cen(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
void callbackSIF(const float *buf, qint32 len, unsigned int channel=0)
void decimate8_inf(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:825
void decimate16_sup(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1300
void decimate2_inf(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
void decimate2_cen(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
void setLog2Decimation(unsigned int channel, unsigned int log2_decim)
int32_t i
Definition: decimators.h:244
SampleSinkFifo * getFifo(unsigned int channel)
void decimate4_cen(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
void decimate4_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:782
void callbackSI16(const qint16 *buf, qint32 len, unsigned int channel=0)
void decimate4_inf(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:582
void decimate2_sup(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
Decimators< qint32, qint16, SDR_RX_SAMP_SZ, 16 > m_decimators16
void decimate8_cen(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
unsigned int getLog2Decimation(unsigned int channel) const
Decimators< qint32, qint16, SDR_RX_SAMP_SZ, 12 > m_decimators12
void decimate16_sup(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
SoapySDRInputThread(SoapySDR::Device *dev, unsigned int nbRxChannels, QObject *parent=0)
void decimate16_inf(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1117
void decimate64_cen(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
void decimate64_inf(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
void setFifo(unsigned int channel, SampleSinkFifo *sampleFifo)
void decimate16_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1483
void decimate32_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:2212
void decimate1(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:462
void decimate1(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)
void decimate16_inf(SampleVector::iterator *it, const float *buf, qint32 nbIAndQ)