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.
hackrfinputthread.cpp
Go to the documentation of this file.
1 // Copyright (C) 2015 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 "hackrfinputthread.h"
19 
20 #include <stdio.h>
21 #include <errno.h>
22 #include <algorithm>
23 
24 #include "dsp/samplesinkfifo.h"
25 
26 HackRFInputThread::HackRFInputThread(hackrf_device* dev, SampleSinkFifo* sampleFifo, QObject* parent) :
27  QThread(parent),
28  m_running(false),
29  m_dev(dev),
30  m_convertBuffer(HACKRF_BLOCKSIZE),
31  m_sampleFifo(sampleFifo),
32  m_samplerate(10),
33  m_log2Decim(0),
34  m_fcPos(0)
35 {
36  std::fill(m_buf, m_buf + 2*HACKRF_BLOCKSIZE, 0);
37 }
38 
40 {
41  stopWork();
42 }
43 
45 {
46  m_startWaitMutex.lock();
47  start();
48  while(!m_running)
49  m_startWaiter.wait(&m_startWaitMutex, 100);
50  m_startWaitMutex.unlock();
51 }
52 
54 {
55  qDebug("HackRFThread::stopWork");
56  m_running = false;
57  wait();
58 }
59 
61 {
62  m_samplerate = samplerate;
63 }
64 
65 void HackRFInputThread::setLog2Decimation(unsigned int log2_decim)
66 {
67  m_log2Decim = log2_decim;
68 }
69 
71 {
72  m_fcPos = fcPos;
73 }
74 
76 {
77  hackrf_error rc;
78 
79  m_running = true;
80  m_startWaiter.wakeAll();
81 
82  if (hackrf_is_streaming(m_dev) == HACKRF_TRUE)
83  {
84  qDebug("HackRFInputThread::run: HackRF is streaming already");
85  }
86  else
87  {
88  qDebug("HackRFInputThread::run: HackRF is not streaming");
89 
90  rc = (hackrf_error) hackrf_start_rx(m_dev, rx_callback, this);
91 
92  if (rc == HACKRF_SUCCESS)
93  {
94  qDebug("HackRFInputThread::run: started HackRF Rx");
95  }
96  else
97  {
98  qDebug("HackRFInputThread::run: failed to start HackRF Rx: %s", hackrf_error_name(rc));
99  }
100  }
101 
102  while ((m_running) && (hackrf_is_streaming(m_dev) == HACKRF_TRUE))
103  {
104  usleep(200000);
105  }
106 
107  if (hackrf_is_streaming(m_dev) == HACKRF_TRUE)
108  {
109  rc = (hackrf_error) hackrf_stop_rx(m_dev);
110 
111  if (rc == HACKRF_SUCCESS)
112  {
113  qDebug("HackRFInputThread::run: stopped HackRF Rx");
114  }
115  else
116  {
117  qDebug("HackRFInputThread::run: failed to stop HackRF Rx: %s", hackrf_error_name(rc));
118  }
119  }
120 
121  m_running = false;
122 }
123 
124 // Decimate according to specified log2 (ex: log2=4 => decim=16)
125 void HackRFInputThread::callback(const qint8* buf, qint32 len)
126 {
127  SampleVector::iterator it = m_convertBuffer.begin();
128 
129  if (m_log2Decim == 0)
130  {
131  m_decimators.decimate1(&it, buf, len);
132  }
133  else
134  {
135  if (m_fcPos == 0) // Infra
136  {
137  switch (m_log2Decim)
138  {
139  case 1:
140  m_decimators.decimate2_inf(&it, buf, len);
141  break;
142  case 2:
143  m_decimators.decimate4_inf_txsync(&it, buf, len);
144  break;
145  case 3:
146  m_decimators.decimate8_inf_txsync(&it, buf, len);
147  break;
148  case 4:
149  m_decimators.decimate16_inf_txsync(&it, buf, len);
150  break;
151  case 5:
152  m_decimators.decimate32_inf_txsync(&it, buf, len);
153  break;
154  case 6:
155  m_decimators.decimate64_inf_txsync(&it, buf, len);
156  break;
157  default:
158  break;
159  }
160  }
161  else if (m_fcPos == 1) // Supra
162  {
163  switch (m_log2Decim)
164  {
165  case 1:
166  m_decimators.decimate2_sup(&it, buf, len);
167  break;
168  case 2:
169  m_decimators.decimate4_sup_txsync(&it, buf, len);
170  break;
171  case 3:
172  m_decimators.decimate8_sup_txsync(&it, buf, len);
173  break;
174  case 4:
175  m_decimators.decimate16_sup_txsync(&it, buf, len);
176  break;
177  case 5:
178  m_decimators.decimate32_sup_txsync(&it, buf, len);
179  break;
180  case 6:
181  m_decimators.decimate64_sup_txsync(&it, buf, len);
182  break;
183  default:
184  break;
185  }
186  }
187  else if (m_fcPos == 2) // Center
188  {
189  switch (m_log2Decim)
190  {
191  case 1:
192  m_decimators.decimate2_cen(&it, buf, len);
193  break;
194  case 2:
195  m_decimators.decimate4_cen(&it, buf, len);
196  break;
197  case 3:
198  m_decimators.decimate8_cen(&it, buf, len);
199  break;
200  case 4:
201  m_decimators.decimate16_cen(&it, buf, len);
202  break;
203  case 5:
204  m_decimators.decimate32_cen(&it, buf, len);
205  break;
206  case 6:
207  m_decimators.decimate64_cen(&it, buf, len);
208  break;
209  default:
210  break;
211  }
212  }
213  }
214 
215  m_sampleFifo->write(m_convertBuffer.begin(), it);
216 }
217 
218 
219 int HackRFInputThread::rx_callback(hackrf_transfer* transfer)
220 {
221  HackRFInputThread *thread = (HackRFInputThread *) transfer->rx_ctx;
222  qint32 bytes_to_write = transfer->valid_length;
223  thread->callback((qint8 *) transfer->buffer, bytes_to_write);
224  return 0;
225 }
void setLog2Decimation(unsigned int log2_decim)
void decimate2_inf(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:498
HackRFInputThread(hackrf_device *dev, SampleSinkFifo *sampleFifo, QObject *parent=NULL)
void decimate4_sup_txsync(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:732
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 decimate64_inf_txsync(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:2911
void decimate2_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:554
uint write(const quint8 *data, uint count)
void callback(const qint8 *buf, qint32 len)
unsigned int uint32_t
Definition: rtptypes_win.h:46
void decimate8_inf_txsync(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:898
unsigned int m_log2Decim
void decimate8_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1057
void decimate8_sup_txsync(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1014
void decimate64_sup_txsync(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:3440
static int rx_callback(hackrf_transfer *transfer)
void decimate16_inf_txsync(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1250
void decimate4_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:782
SampleSinkFifo * m_sampleFifo
QWaitCondition m_startWaiter
hackrf_device * m_dev
#define HACKRF_BLOCKSIZE
void decimate32_sup_txsync(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:2155
void decimate16_sup_txsync(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1433
void setSamplerate(uint32_t samplerate)
qint16 m_buf[2 *HACKRF_BLOCKSIZE]
void decimate16_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1483
void setFcPos(int fcPos)
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
Decimators< qint32, qint8, SDR_RX_SAMP_SZ, 8 > m_decimators
SampleVector m_convertBuffer
void decimate32_inf_txsync(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1845
void decimate4_inf_txsync(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:632