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.
Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
XTRXOutputThread Class Reference

#include <xtrxoutputthread.h>

+ Inheritance diagram for XTRXOutputThread:
+ Collaboration diagram for XTRXOutputThread:

Classes

struct  Channel
 

Public Member Functions

 XTRXOutputThread (struct xtrx_dev *dev, unsigned int nbChannels, unsigned int uniqueChannelIndex=0, QObject *parent=0)
 
 ~XTRXOutputThread ()
 
virtual void startWork ()
 
virtual void stopWork ()
 
virtual bool isRunning ()
 
unsigned int getNbChannels () const
 
void setLog2Interpolation (unsigned int channel, unsigned int log2_interp)
 
unsigned int getLog2Interpolation (unsigned int channel) const
 
void setFifo (unsigned int channel, SampleSourceFifo *sampleFifo)
 
SampleSourceFifogetFifo (unsigned int channel)
 

Private Member Functions

void run ()
 
unsigned int getNbFifos ()
 
void callback (qint16 *buf, qint32 len)
 
void callbackSO (qint16 *buf, qint32 len)
 
void callbackMO (qint16 *buf0, qint16 *buf1, qint32 len)
 

Private Attributes

QMutex m_startWaitMutex
 
QWaitCondition m_startWaiter
 
bool m_running
 
struct xtrx_dev * m_dev
 
Channelm_channels
 Array of channels dynamically allocated for the given number of Rx channels. More...
 
unsigned int m_nbChannels
 
unsigned int m_uniqueChannelIndex
 

Detailed Description

Definition at line 33 of file xtrxoutputthread.h.

Constructor & Destructor Documentation

◆ XTRXOutputThread()

XTRXOutputThread::XTRXOutputThread ( struct xtrx_dev *  dev,
unsigned int  nbChannels,
unsigned int  uniqueChannelIndex = 0,
QObject *  parent = 0 
)

Definition at line 27 of file xtrxoutputthread.cpp.

References m_channels.

27  :
28  QThread(parent),
29  m_running(false),
30  m_dev(dev),
31  m_nbChannels(nbChannels),
32  m_uniqueChannelIndex(uniqueChannelIndex)
33 {
34  qDebug("XTRXOutputThread::XTRXOutputThread: nbChannels: %u uniqueChannelIndex: %u", nbChannels, uniqueChannelIndex);
35  m_channels = new Channel[2];
36 }
unsigned int m_nbChannels
Channel * m_channels
Array of channels dynamically allocated for the given number of Rx channels.
struct xtrx_dev * m_dev
unsigned int m_uniqueChannelIndex

◆ ~XTRXOutputThread()

XTRXOutputThread::~XTRXOutputThread ( )

Definition at line 38 of file xtrxoutputthread.cpp.

References m_channels, m_running, and stopWork().

39 {
40  qDebug("XTRXOutputThread::~XTRXOutputThread");
41 
42  if (m_running) {
43  stopWork();
44  }
45 
46  delete[] m_channels;
47 }
virtual void stopWork()
Channel * m_channels
Array of channels dynamically allocated for the given number of Rx channels.
+ Here is the call graph for this function:

Member Function Documentation

◆ callback()

void XTRXOutputThread::callback ( qint16 *  buf,
qint32  len 
)
private

Definition at line 225 of file xtrxoutputthread.cpp.

References SampleSourceFifo::getRWBalance(), Interpolators< T, SdrBits, OutputBits >::interpolate1(), Interpolators< T, SdrBits, OutputBits >::interpolate16_cen(), Interpolators< T, SdrBits, OutputBits >::interpolate2_cen(), Interpolators< T, SdrBits, OutputBits >::interpolate32_cen(), Interpolators< T, SdrBits, OutputBits >::interpolate4_cen(), Interpolators< T, SdrBits, OutputBits >::interpolate64_cen(), Interpolators< T, SdrBits, OutputBits >::interpolate8_cen(), m_channels, XTRXOutputThread::Channel::m_interpolators, XTRXOutputThread::Channel::m_sampleFifo, m_uniqueChannelIndex, and SampleSourceFifo::readAdvance().

226 {
227  if (m_channels[m_uniqueChannelIndex].m_sampleFifo)
228  {
230 
231  if (bal < -0.25) {
232  qDebug("XTRXOutputThread::callbackSO: read lags: %f", bal);
233  } else if (bal > 0.25) {
234  qDebug("XTRXOutputThread::callbackSO: read leads: %f", bal);
235  }
236 
237  SampleVector::iterator beginRead;
239  beginRead -= len;
240 
241  if (m_channels[m_uniqueChannelIndex].m_log2Interp == 0)
242  {
244  }
245  else
246  {
247  switch (m_channels[m_uniqueChannelIndex].m_log2Interp)
248  {
249  case 1:
251  break;
252  case 2:
254  break;
255  case 3:
257  break;
258  case 4:
260  break;
261  case 5:
263  break;
264  case 6:
266  break;
267  default:
268  break;
269  }
270  }
271  }
272  else
273  {
274  std::fill(buf, buf+2*len, 0);
275  }
276 }
void interpolate64_cen(SampleVector::iterator *it, T *buf, qint32 len, bool invertIQ=false)
float getRWBalance() const
void interpolate32_cen(SampleVector::iterator *it, T *buf, qint32 len, bool invertIQ=false)
Channel * m_channels
Array of channels dynamically allocated for the given number of Rx channels.
void interpolate8_cen(SampleVector::iterator *it, T *buf, qint32 len, bool invertIQ=false)
void interpolate2_cen(SampleVector::iterator *it, T *buf, qint32 len, bool invertIQ=false)
void readAdvance(SampleVector::iterator &readUntil, unsigned int nbSamples)
SampleSourceFifo * m_sampleFifo
Interpolators< qint16, SDR_TX_SAMP_SZ, 12 > m_interpolators
void interpolate1(SampleVector::iterator *it, T *buf, qint32 len, bool invertIQ=false)
void interpolate16_cen(SampleVector::iterator *it, T *buf, qint32 len, bool invertIQ=false)
void interpolate4_cen(SampleVector::iterator *it, T *buf, qint32 len, bool invertIQ=false)
unsigned int m_uniqueChannelIndex
+ Here is the call graph for this function:

◆ callbackMO()

void XTRXOutputThread::callbackMO ( qint16 *  buf0,
qint16 *  buf1,
qint32  len 
)
private

Definition at line 331 of file xtrxoutputthread.cpp.

References callbackSO(), and m_uniqueChannelIndex.

332 {
333  unsigned int uniqueChannelIndex = m_uniqueChannelIndex;
334 
335  // channel 0
337  callbackSO(buf0, len);
338  // channel 1
340  callbackSO(buf1, len);
341 
342  m_uniqueChannelIndex = uniqueChannelIndex;
343 }
void callbackSO(qint16 *buf, qint32 len)
unsigned int m_uniqueChannelIndex
+ Here is the call graph for this function:

◆ callbackSO()

void XTRXOutputThread::callbackSO ( qint16 *  buf,
qint32  len 
)
private

Definition at line 278 of file xtrxoutputthread.cpp.

References SampleSourceFifo::getRWBalance(), Interpolators< T, SdrBits, OutputBits >::interpolate1(), Interpolators< T, SdrBits, OutputBits >::interpolate16_cen(), Interpolators< T, SdrBits, OutputBits >::interpolate2_cen(), Interpolators< T, SdrBits, OutputBits >::interpolate32_cen(), Interpolators< T, SdrBits, OutputBits >::interpolate4_cen(), Interpolators< T, SdrBits, OutputBits >::interpolate64_cen(), Interpolators< T, SdrBits, OutputBits >::interpolate8_cen(), m_channels, XTRXOutputThread::Channel::m_interpolators, XTRXOutputThread::Channel::m_sampleFifo, m_uniqueChannelIndex, and SampleSourceFifo::readAdvance().

Referenced by callbackMO(), and run().

279 {
280  if (m_channels[m_uniqueChannelIndex].m_sampleFifo)
281  {
283 
284  if (bal < -0.25) {
285  qDebug("XTRXOutputThread::callbackSO: read lags: %f", bal);
286  } else if (bal > 0.25) {
287  qDebug("XTRXOutputThread::callbackSO: read leads: %f", bal);
288  }
289 
290  SampleVector::iterator beginRead;
292  beginRead -= len;
293 
294  if (m_channels[m_uniqueChannelIndex].m_log2Interp == 0)
295  {
297  }
298  else
299  {
300  switch (m_channels[m_uniqueChannelIndex].m_log2Interp)
301  {
302  case 1:
304  break;
305  case 2:
307  break;
308  case 3:
310  break;
311  case 4:
313  break;
314  case 5:
316  break;
317  case 6:
319  break;
320  default:
321  break;
322  }
323  }
324  }
325  else
326  {
327  std::fill(buf, buf+2*len, 0);
328  }
329 }
void interpolate64_cen(SampleVector::iterator *it, T *buf, qint32 len, bool invertIQ=false)
float getRWBalance() const
void interpolate32_cen(SampleVector::iterator *it, T *buf, qint32 len, bool invertIQ=false)
Channel * m_channels
Array of channels dynamically allocated for the given number of Rx channels.
void interpolate8_cen(SampleVector::iterator *it, T *buf, qint32 len, bool invertIQ=false)
void interpolate2_cen(SampleVector::iterator *it, T *buf, qint32 len, bool invertIQ=false)
void readAdvance(SampleVector::iterator &readUntil, unsigned int nbSamples)
SampleSourceFifo * m_sampleFifo
Interpolators< qint16, SDR_TX_SAMP_SZ, 12 > m_interpolators
void interpolate1(SampleVector::iterator *it, T *buf, qint32 len, bool invertIQ=false)
void interpolate16_cen(SampleVector::iterator *it, T *buf, qint32 len, bool invertIQ=false)
void interpolate4_cen(SampleVector::iterator *it, T *buf, qint32 len, bool invertIQ=false)
unsigned int m_uniqueChannelIndex
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getFifo()

SampleSourceFifo * XTRXOutputThread::getFifo ( unsigned int  channel)

Definition at line 104 of file xtrxoutputthread.cpp.

References m_channels, and XTRXOutputThread::Channel::m_sampleFifo.

Referenced by getNbChannels(), and XTRXOutput::start().

105 {
106  if (channel < 2) {
107  return m_channels[channel].m_sampleFifo;
108  } else {
109  return 0;
110  }
111 }
Channel * m_channels
Array of channels dynamically allocated for the given number of Rx channels.
SampleSourceFifo * m_sampleFifo
+ Here is the caller graph for this function:

◆ getLog2Interpolation()

unsigned int XTRXOutputThread::getLog2Interpolation ( unsigned int  channel) const

Definition at line 88 of file xtrxoutputthread.cpp.

References m_channels, and XTRXOutputThread::Channel::m_log2Interp.

Referenced by getNbChannels(), and XTRXOutput::start().

89 {
90  if (channel < 2) {
91  return m_channels[channel].m_log2Interp;
92  } else {
93  return 0;
94  }
95 }
Channel * m_channels
Array of channels dynamically allocated for the given number of Rx channels.
+ Here is the caller graph for this function:

◆ getNbChannels()

unsigned int XTRXOutputThread::getNbChannels ( ) const
inline

Definition at line 44 of file xtrxoutputthread.h.

References getFifo(), getLog2Interpolation(), m_nbChannels, setFifo(), and setLog2Interpolation().

Referenced by XTRXOutput::start(), and XTRXOutput::stop().

44 { return m_nbChannels; }
unsigned int m_nbChannels
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getNbFifos()

unsigned int XTRXOutputThread::getNbFifos ( )
private

Definition at line 67 of file xtrxoutputthread.cpp.

References i, and m_channels.

Referenced by run().

68 {
69  unsigned int fifoCount = 0;
70 
71  for (unsigned int i = 0; i < 2; i++)
72  {
73  if (m_channels[i].m_sampleFifo) {
74  fifoCount++;
75  }
76  }
77 
78  return fifoCount;
79 }
Channel * m_channels
Array of channels dynamically allocated for the given number of Rx channels.
int32_t i
Definition: decimators.h:244
+ Here is the caller graph for this function:

◆ isRunning()

virtual bool XTRXOutputThread::isRunning ( )
inlinevirtual

Implements DeviceXTRXShared::ThreadInterface.

Definition at line 43 of file xtrxoutputthread.h.

References m_running.

Referenced by XTRXOutput::applySettings().

43 { return m_running; }
+ Here is the caller graph for this function:

◆ run()

void XTRXOutputThread::run ( )
private

Definition at line 113 of file xtrxoutputthread.cpp.

References DeviceXTRX::blockSize, callbackSO(), getNbFifos(), i, m_dev, m_nbChannels, m_running, m_startWaiter, and m_uniqueChannelIndex.

114 {
115  int res;
116 
117  m_running = true;
118  m_startWaiter.wakeAll();
119 
120  unsigned int nbFifos = getNbFifos();
121 
122  if ((m_nbChannels != 0) && (nbFifos != 0))
123  {
124  xtrx_run_params params;
125  xtrx_run_params_init(&params);
126 
127  params.dir = XTRX_TX;
128  params.tx_repeat_buf = 0;
129  params.tx.paketsize = 2*DeviceXTRX::blockSize;
130  params.tx.chs = XTRX_CH_AB;
131  params.tx.wfmt = XTRX_WF_16;
132  params.tx.hfmt = XTRX_IQ_INT16;
133  params.tx.flags |= XTRX_RSP_SWAP_IQ;
134 
135  if (m_nbChannels == 1)
136  {
137  qDebug("XTRXOutputThread::run: SO mode for channel #%u", m_uniqueChannelIndex);
138  params.tx.flags |= XTRX_RSP_SISO_MODE;
139 
140  if (m_uniqueChannelIndex == 1) {
141  params.tx.flags |= XTRX_RSP_SWAP_AB;
142  }
143  }
144 
145  res = xtrx_run_ex(m_dev, &params);
146 
147  if (res != 0)
148  {
149  qCritical("XTRXOutputThread::run: could not start stream err:%d", res);
150  m_running = false;
151  }
152  else
153  {
154  std::this_thread::sleep_for(std::chrono::milliseconds(50));
155  qDebug("XTRXOutputThread::run: stream started");
156  }
157 
158  const unsigned int elemSize = 4; // XTRX uses 4 byte I+Q samples
159  std::vector<std::vector<char>> buffMem(m_nbChannels, std::vector<char>(elemSize*DeviceXTRX::blockSize));
160  std::vector<void *> buffs(m_nbChannels);
161  master_ts ts = 4096*1024;
162 
163  for (std::size_t i = 0; i < m_nbChannels; i++) {
164  buffs[i] = buffMem[i].data();
165  }
166 
167  xtrx_send_ex_info_t nfo;
168  nfo.samples = DeviceXTRX::blockSize;
169  nfo.buffer_count = m_nbChannels;
170  nfo.buffers = (void* const*) buffs.data();
171  nfo.flags = XTRX_TX_DONT_BUFFER; // | XTRX_TX_SEND_ZEROS;
172  nfo.timeout = 0;
173  nfo.out_txlatets = 0;
174  nfo.ts = ts;
175 
176  while (m_running)
177  {
178 // if (m_nbChannels > 1) {
179 // callbackMO((qint16*) buffs[0], (qint16*) buffs[1], nfo.samples);
180 // } else {
181 // callbackSO((qint16*) buffs[0], nfo.samples);
182 // }
183 
184  callbackSO((qint16*) buffs[0], nfo.samples);
185  res = xtrx_send_sync_ex(m_dev, &nfo);
186 
187  if (res < 0)
188  {
189  qCritical("XTRXOutputThread::run send error: %d", res);
190  qDebug("XTRXOutputThread::run: out_samples: %u out_flags: %u", nfo.out_samples, nfo.out_flags);
191  break;
192  }
193 
194  if (nfo.out_flags & XTRX_TX_DISCARDED_TO) {
195  qDebug("XTRXOutputThread::run: underrun");
196  }
197 
198  if (nfo.out_txlatets) {
199  qDebug("XTRXOutputThread::run: out_txlatets: %lu", nfo.out_txlatets);
200  }
201 
202  nfo.ts += DeviceXTRX::blockSize;
203  }
204 
205  res = xtrx_stop(m_dev, XTRX_TX);
206 
207  if (res != 0)
208  {
209  qCritical("XTRXOutputThread::run: could not stop stream");
210  }
211  else
212  {
213  std::this_thread::sleep_for(std::chrono::milliseconds(50));
214  qDebug("XTRXOutputThread::run: stream stopped");
215  }
216  }
217  else
218  {
219  qWarning("XTRXOutputThread::run: no channels or FIFO allocated. Aborting");
220  }
221 
222  m_running = false;
223 }
void callbackSO(qint16 *buf, qint32 len)
unsigned int m_nbChannels
int32_t i
Definition: decimators.h:244
struct xtrx_dev * m_dev
static const unsigned int blockSize
Definition: devicextrx.h:44
unsigned int getNbFifos()
unsigned int m_uniqueChannelIndex
QWaitCondition m_startWaiter
+ Here is the call graph for this function:

◆ setFifo()

void XTRXOutputThread::setFifo ( unsigned int  channel,
SampleSourceFifo sampleFifo 
)

Definition at line 97 of file xtrxoutputthread.cpp.

References m_channels, and XTRXOutputThread::Channel::m_sampleFifo.

Referenced by getNbChannels(), XTRXOutput::start(), and XTRXOutput::stop().

98 {
99  if (channel < 2) {
100  m_channels[channel].m_sampleFifo = sampleFifo;
101  }
102 }
Channel * m_channels
Array of channels dynamically allocated for the given number of Rx channels.
SampleSourceFifo * m_sampleFifo
+ Here is the caller graph for this function:

◆ setLog2Interpolation()

void XTRXOutputThread::setLog2Interpolation ( unsigned int  channel,
unsigned int  log2_interp 
)

Definition at line 81 of file xtrxoutputthread.cpp.

References m_channels, and XTRXOutputThread::Channel::m_log2Interp.

Referenced by XTRXOutput::applySettings(), getNbChannels(), XTRXOutput::start(), and XTRXOutput::stop().

82 {
83  if (channel < 2) {
84  m_channels[channel].m_log2Interp = log2_interp;
85  }
86 }
Channel * m_channels
Array of channels dynamically allocated for the given number of Rx channels.
+ Here is the caller graph for this function:

◆ startWork()

void XTRXOutputThread::startWork ( )
virtual

Implements DeviceXTRXShared::ThreadInterface.

Definition at line 49 of file xtrxoutputthread.cpp.

References m_running, m_startWaiter, and m_startWaitMutex.

Referenced by XTRXOutput::applySettings(), XTRXOutput::start(), and XTRXOutput::stop().

50 {
51  m_startWaitMutex.lock();
52  start();
53 
54  while(!m_running) {
55  m_startWaiter.wait(&m_startWaitMutex, 100);
56  }
57 
58  m_startWaitMutex.unlock();
59 }
QWaitCondition m_startWaiter
+ Here is the caller graph for this function:

◆ stopWork()

void XTRXOutputThread::stopWork ( )
virtual

Implements DeviceXTRXShared::ThreadInterface.

Definition at line 61 of file xtrxoutputthread.cpp.

References m_running.

Referenced by XTRXOutput::applySettings(), XTRXOutput::start(), XTRXOutput::stop(), and ~XTRXOutputThread().

62 {
63  m_running = false;
64  wait();
65 }
+ Here is the caller graph for this function:

Member Data Documentation

◆ m_channels

Channel* XTRXOutputThread::m_channels
private

Array of channels dynamically allocated for the given number of Rx channels.

Definition at line 71 of file xtrxoutputthread.h.

Referenced by callback(), callbackSO(), getFifo(), getLog2Interpolation(), getNbFifos(), setFifo(), setLog2Interpolation(), XTRXOutputThread(), and ~XTRXOutputThread().

◆ m_dev

struct xtrx_dev* XTRXOutputThread::m_dev
private

Definition at line 69 of file xtrxoutputthread.h.

Referenced by run().

◆ m_nbChannels

unsigned int XTRXOutputThread::m_nbChannels
private

Definition at line 72 of file xtrxoutputthread.h.

Referenced by getNbChannels(), and run().

◆ m_running

bool XTRXOutputThread::m_running
private

Definition at line 68 of file xtrxoutputthread.h.

Referenced by isRunning(), run(), startWork(), stopWork(), and ~XTRXOutputThread().

◆ m_startWaiter

QWaitCondition XTRXOutputThread::m_startWaiter
private

Definition at line 67 of file xtrxoutputthread.h.

Referenced by run(), and startWork().

◆ m_startWaitMutex

QMutex XTRXOutputThread::m_startWaitMutex
private

Definition at line 66 of file xtrxoutputthread.h.

Referenced by startWork().

◆ m_uniqueChannelIndex

unsigned int XTRXOutputThread::m_uniqueChannelIndex
private

Definition at line 73 of file xtrxoutputthread.h.

Referenced by callback(), callbackMO(), callbackSO(), and run().


The documentation for this class was generated from the following files: