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.
bladerf2inputthread.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 "dsp/samplesinkfifo.h"
19 
20 #include "bladerf2inputthread.h"
21 
22 BladeRF2InputThread::BladeRF2InputThread(struct bladerf* dev, unsigned int nbRxChannels, QObject* parent) :
23  QThread(parent),
24  m_running(false),
25  m_dev(dev),
26  m_nbChannels(nbRxChannels)
27 {
28  qDebug("BladeRF2InputThread::BladeRF2InputThread");
29  m_channels = new Channel[nbRxChannels];
30 
31  for (unsigned int i = 0; i < nbRxChannels; i++) {
33  }
34 
35  m_buf = new qint16[2*DeviceBladeRF2::blockSize*nbRxChannels];
36 }
37 
39 {
40  qDebug("BladeRF2InputThread::~BladeRF2InputThread");
41 
42  if (m_running) {
43  stopWork();
44  }
45 
46  delete[] m_buf;
47  delete[] m_channels;
48 }
49 
51 {
52  m_startWaitMutex.lock();
53  start();
54 
55  while(!m_running) {
56  m_startWaiter.wait(&m_startWaitMutex, 100);
57  }
58 
59  m_startWaitMutex.unlock();
60 }
61 
63 {
64  m_running = false;
65  wait();
66 }
67 
69 {
70  int res;
71 
72  m_running = true;
73  m_startWaiter.wakeAll();
74 
75  unsigned int nbFifos = getNbFifos();
76 
77  if ((m_nbChannels > 0) && (nbFifos > 0))
78  {
79  int status;
80 
81  if (m_nbChannels > 1) {
82  status = bladerf_sync_config(m_dev, BLADERF_RX_X2, BLADERF_FORMAT_SC16_Q11, 64, 8192, 32, 10000);
83  } else {
84  status = bladerf_sync_config(m_dev, BLADERF_RX_X1, BLADERF_FORMAT_SC16_Q11, 64, 8192, 32, 10000);
85  }
86 
87  if (status < 0)
88  {
89  qCritical("BladeRF2InputThread::run: cannot configure streams: %s", bladerf_strerror(status));
90  }
91  else
92  {
93  qDebug("BladeRF2InputThread::run: start running loop");
94  while (m_running)
95  {
96  if (m_nbChannels > 1) {
97  res = bladerf_sync_rx(m_dev, m_buf, DeviceBladeRF2::blockSize*m_nbChannels, NULL, 10000);
98  } else {
99  res = bladerf_sync_rx(m_dev, m_buf, DeviceBladeRF2::blockSize, NULL, 10000);
100  }
101 
102  if (res < 0)
103  {
104  qCritical("BladeRF2InputThread::run sync Rx error: %s", bladerf_strerror(res));
105  break;
106  }
107 
108  if (m_nbChannels > 1) {
110  } else {
112  }
113  }
114  qDebug("BladeRF2InputThread::run: stop running loop");
115  }
116  }
117  else
118  {
119  qWarning("BladeRF2InputThread::run: no channels or FIFO allocated. Aborting");
120  }
121 
122 
123  m_running = false;
124 }
125 
127 {
128  unsigned int fifoCount = 0;
129 
130  for (unsigned int i = 0; i < m_nbChannels; i++)
131  {
132  if (m_channels[i].m_sampleFifo) {
133  fifoCount++;
134  }
135  }
136 
137  return fifoCount;
138 }
139 
140 void BladeRF2InputThread::setLog2Decimation(unsigned int channel, unsigned int log2_decim)
141 {
142  if (channel < m_nbChannels) {
143  m_channels[channel].m_log2Decim = log2_decim;
144  }
145 }
146 
147 unsigned int BladeRF2InputThread::getLog2Decimation(unsigned int channel) const
148 {
149  if (channel < m_nbChannels) {
150  return m_channels[channel].m_log2Decim;
151  } else {
152  return 0;
153  }
154 }
155 
156 void BladeRF2InputThread::setFcPos(unsigned int channel, int fcPos)
157 {
158  if (channel < m_nbChannels) {
159  m_channels[channel].m_fcPos = fcPos;
160  }
161 }
162 
163 int BladeRF2InputThread::getFcPos(unsigned int channel) const
164 {
165  if (channel < m_nbChannels) {
166  return m_channels[channel].m_fcPos;
167  } else {
168  return 0;
169  }
170 }
171 
172 void BladeRF2InputThread::setFifo(unsigned int channel, SampleSinkFifo *sampleFifo)
173 {
174  if (channel < m_nbChannels) {
175  m_channels[channel].m_sampleFifo = sampleFifo;
176  }
177 }
178 
180 {
181  if (channel < m_nbChannels) {
182  return m_channels[channel].m_sampleFifo;
183  } else {
184  return 0;
185  }
186 }
187 
188 void BladeRF2InputThread::callbackMI(const qint16* buf, qint32 samplesPerChannel)
189 {
190  // TODO: write a set of decimators that can take interleaved samples in input directly
191  int status = bladerf_deinterleave_stream_buffer(BLADERF_RX_X2, BLADERF_FORMAT_SC16_Q11 , samplesPerChannel*m_nbChannels, (void *) buf);
192 
193  if (status < 0)
194  {
195  qCritical("BladeRF2InputThread::callbackMI: cannot de-interleave buffer: %s", bladerf_strerror(status));
196  return;
197  }
198 
199  for (unsigned int channel = 0; channel < m_nbChannels; channel++)
200  {
201  if (m_channels[channel].m_sampleFifo) {
202  callbackSI(&buf[2*samplesPerChannel*channel], 2*samplesPerChannel, channel);
203  }
204  }
205 }
206 
207 void BladeRF2InputThread::callbackSI(const qint16* buf, qint32 len, unsigned int channel)
208 {
209  SampleVector::iterator it = m_channels[channel].m_convertBuffer.begin();
210 
211  if (m_channels[channel].m_log2Decim == 0)
212  {
213  m_channels[channel].m_decimators.decimate1(&it, buf, len);
214  }
215  else
216  {
217  if (m_channels[channel].m_fcPos == 0) // Infra
218  {
219  switch (m_channels[channel].m_log2Decim)
220  {
221  case 1:
222  m_channels[channel].m_decimators.decimate2_inf(&it, buf, len);
223  break;
224  case 2:
225  m_channels[channel].m_decimators.decimate4_inf(&it, buf, len);
226  break;
227  case 3:
228  m_channels[channel].m_decimators.decimate8_inf(&it, buf, len);
229  break;
230  case 4:
231  m_channels[channel].m_decimators.decimate16_inf(&it, buf, len);
232  break;
233  case 5:
234  m_channels[channel].m_decimators.decimate32_inf(&it, buf, len);
235  break;
236  case 6:
237  m_channels[channel].m_decimators.decimate64_inf(&it, buf, len);
238  break;
239  default:
240  break;
241  }
242  }
243  else if (m_channels[channel].m_fcPos == 1) // Supra
244  {
245  switch (m_channels[channel].m_log2Decim)
246  {
247  case 1:
248  m_channels[channel].m_decimators.decimate2_sup(&it, buf, len);
249  break;
250  case 2:
251  m_channels[channel].m_decimators.decimate4_sup(&it, buf, len);
252  break;
253  case 3:
254  m_channels[channel].m_decimators.decimate8_sup(&it, buf, len);
255  break;
256  case 4:
257  m_channels[channel].m_decimators.decimate16_sup(&it, buf, len);
258  break;
259  case 5:
260  m_channels[channel].m_decimators.decimate32_sup(&it, buf, len);
261  break;
262  case 6:
263  m_channels[channel].m_decimators.decimate64_sup(&it, buf, len);
264  break;
265  default:
266  break;
267  }
268  }
269  else if (m_channels[channel].m_fcPos == 2) // Center
270  {
271  switch (m_channels[channel].m_log2Decim)
272  {
273  case 1:
274  m_channels[channel].m_decimators.decimate2_cen(&it, buf, len);
275  break;
276  case 2:
277  m_channels[channel].m_decimators.decimate4_cen(&it, buf, len);
278  break;
279  case 3:
280  m_channels[channel].m_decimators.decimate8_cen(&it, buf, len);
281  break;
282  case 4:
283  m_channels[channel].m_decimators.decimate16_cen(&it, buf, len);
284  break;
285  case 5:
286  m_channels[channel].m_decimators.decimate32_cen(&it, buf, len);
287  break;
288  case 6:
289  m_channels[channel].m_decimators.decimate64_cen(&it, buf, len);
290  break;
291  default:
292  break;
293  }
294  }
295  }
296 
297  m_channels[channel].m_sampleFifo->write(m_channels[channel].m_convertBuffer.begin(), it);
298 }
299 
unsigned int getLog2Decimation(unsigned int channel) const
void decimate2_inf(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:498
void decimate64_sup(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:2975
Channel * m_channels
Array of channels dynamically allocated for the given number of Rx channels.
void callbackSI(const qint16 *buf, qint32 len, unsigned int channel=0)
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)
void decimate8_sup(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:941
static const unsigned int blockSize
void setFcPos(unsigned int channel, int fcPos)
void decimate64_inf(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:2418
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
void decimate4_sup(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:682
void decimate8_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1057
void callbackMI(const qint16 *buf, qint32 samplesPerChannel)
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
qint16 * m_buf
Full buffer for SISO or MIMO operation.
int32_t i
Definition: decimators.h:244
int getFcPos(unsigned int channel) const
void decimate4_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:782
struct bladerf * m_dev
void setFifo(unsigned int channel, SampleSinkFifo *sampleFifo)
void decimate4_inf(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:582
QWaitCondition m_startWaiter
void setLog2Decimation(unsigned int channel, unsigned int log2_decim)
void decimate16_inf(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1117
Decimators< qint32, qint16, SDR_RX_SAMP_SZ, 12 > m_decimators
BladeRF2InputThread(struct bladerf *dev, unsigned int nbRxChannels, QObject *parent=NULL)
SampleSinkFifo * getFifo(unsigned int channel)
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