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.
airspythread.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 <stdio.h>
19 #include <errno.h>
20 #include <algorithm>
21 
22 #include "airspythread.h"
23 
24 #include "dsp/samplesinkfifo.h"
25 
27 
28 AirspyThread::AirspyThread(struct airspy_device* dev, SampleSinkFifo* sampleFifo, QObject* parent) :
29  QThread(parent),
30  m_running(false),
31  m_dev(dev),
32  m_convertBuffer(AIRSPY_BLOCKSIZE),
33  m_sampleFifo(sampleFifo),
34  m_samplerate(10),
35  m_log2Decim(0),
36  m_fcPos(0)
37 {
38  m_this = this;
39  std::fill(m_buf, m_buf + 2*AIRSPY_BLOCKSIZE, 0);
40 }
41 
43 {
44  stopWork();
45  m_this = 0;
46 }
47 
49 {
50  m_startWaitMutex.lock();
51  start();
52  while(!m_running)
53  m_startWaiter.wait(&m_startWaitMutex, 100);
54  m_startWaitMutex.unlock();
55 }
56 
58 {
59  qDebug("AirspyThread::stopWork");
60  m_running = false;
61  wait();
62 }
63 
65 {
66  m_samplerate = samplerate;
67 }
68 
69 void AirspyThread::setLog2Decimation(unsigned int log2_decim)
70 {
71  m_log2Decim = log2_decim;
72 }
73 
74 void AirspyThread::setFcPos(int fcPos)
75 {
76  m_fcPos = fcPos;
77 }
78 
80 {
81  airspy_error rc;
82 
83  m_running = true;
84  m_startWaiter.wakeAll();
85 
86  rc = (airspy_error) airspy_start_rx(m_dev, rx_callback, NULL);
87 
88  if (rc != AIRSPY_SUCCESS)
89  {
90  qCritical("AirspyThread::run: failed to start Airspy Rx: %s", airspy_error_name(rc));
91  }
92  else
93  {
94  while ((m_running) && (airspy_is_streaming(m_dev) == AIRSPY_TRUE))
95  {
96  sleep(1);
97  }
98  }
99 
100  rc = (airspy_error) airspy_stop_rx(m_dev);
101 
102  if (rc == AIRSPY_SUCCESS)
103  {
104  qDebug("AirspyThread::run: stopped Airspy Rx");
105  }
106  else
107  {
108  qDebug("AirspyThread::run: failed to stop Airspy Rx: %s", airspy_error_name(rc));
109  }
110 
111  m_running = false;
112 }
113 
114 // Decimate according to specified log2 (ex: log2=4 => decim=16)
115 void AirspyThread::callback(const qint16* buf, qint32 len)
116 {
117  SampleVector::iterator it = m_convertBuffer.begin();
118 
119  if (m_log2Decim == 0)
120  {
121  m_decimators.decimate1(&it, buf, len);
122  }
123  else
124  {
125  if (m_fcPos == 0) // Infra
126  {
127  switch (m_log2Decim)
128  {
129  case 1:
130  m_decimators.decimate2_inf(&it, buf, len);
131  break;
132  case 2:
133  m_decimators.decimate4_inf(&it, buf, len);
134  break;
135  case 3:
136  m_decimators.decimate8_inf(&it, buf, len);
137  break;
138  case 4:
139  m_decimators.decimate16_inf(&it, buf, len);
140  break;
141  case 5:
142  m_decimators.decimate32_inf(&it, buf, len);
143  break;
144  case 6:
145  m_decimators.decimate64_inf(&it, buf, len);
146  break;
147  default:
148  break;
149  }
150  }
151  else if (m_fcPos == 1) // Supra
152  {
153  switch (m_log2Decim)
154  {
155  case 1:
156  m_decimators.decimate2_sup(&it, buf, len);
157  break;
158  case 2:
159  m_decimators.decimate4_sup(&it, buf, len);
160  break;
161  case 3:
162  m_decimators.decimate8_sup(&it, buf, len);
163  break;
164  case 4:
165  m_decimators.decimate16_sup(&it, buf, len);
166  break;
167  case 5:
168  m_decimators.decimate32_sup(&it, buf, len);
169  break;
170  case 6:
171  m_decimators.decimate64_sup(&it, buf, len);
172  break;
173  default:
174  break;
175  }
176  }
177  else if (m_fcPos == 2) // Center
178  {
179  switch (m_log2Decim)
180  {
181  case 1:
182  m_decimators.decimate2_cen(&it, buf, len);
183  break;
184  case 2:
185  m_decimators.decimate4_cen(&it, buf, len);
186  break;
187  case 3:
188  m_decimators.decimate8_cen(&it, buf, len);
189  break;
190  case 4:
191  m_decimators.decimate16_cen(&it, buf, len);
192  break;
193  case 5:
194  m_decimators.decimate32_cen(&it, buf, len);
195  break;
196  case 6:
197  m_decimators.decimate64_cen(&it, buf, len);
198  break;
199  default:
200  break;
201  }
202  }
203  }
204 
205  m_sampleFifo->write(m_convertBuffer.begin(), it);
206 }
207 
208 
209 int AirspyThread::rx_callback(airspy_transfer_t* transfer)
210 {
211  qint32 bytes_to_write = transfer->sample_count * sizeof(qint16);
212  m_this->callback((qint16 *) transfer->samples, bytes_to_write);
213  return 0;
214 }
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
#define AIRSPY_BLOCKSIZE
Definition: airspythread.h:29
qint16 m_buf[2 *AIRSPY_BLOCKSIZE]
Definition: airspythread.h:50
unsigned int m_log2Decim
Definition: airspythread.h:55
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 int rx_callback(airspy_transfer_t *transfer)
static AirspyThread * m_this
Definition: airspythread.h:57
AirspyThread(struct airspy_device *dev, SampleSinkFifo *sampleFifo, QObject *parent=NULL)
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
struct airspy_device * m_dev
Definition: airspythread.h:49
void decimate32_sup(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1902
void callback(const qint16 *buf, qint32 len)
unsigned int uint32_t
Definition: rtptypes_win.h:46
void decimate4_sup(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:682
QMutex m_startWaitMutex
Definition: airspythread.h:45
void decimate8_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1057
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 setLog2Decimation(unsigned int log2_decim)
Decimators< qint32, qint16, SDR_RX_SAMP_SZ, 12 > m_decimators
Definition: airspythread.h:59
void decimate4_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:782
SampleSinkFifo * m_sampleFifo
Definition: airspythread.h:52
SampleVector m_convertBuffer
Definition: airspythread.h:51
void decimate4_inf(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:582
void setSamplerate(uint32_t samplerate)
void setFcPos(int fcPos)
QWaitCondition m_startWaiter
Definition: airspythread.h:46
void decimate16_inf(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1117
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 startWork()