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
BladeRF2OutputThread Class Reference

#include <bladerf2outputthread.h>

Inherits QThread.

+ Collaboration diagram for BladeRF2OutputThread:

Classes

struct  Channel
 

Public Member Functions

 BladeRF2OutputThread (struct bladerf *dev, unsigned int nbTxChannels, QObject *parent=0)
 
 ~BladeRF2OutputThread ()
 
void startWork ()
 
void stopWork ()
 
bool isRunning () const
 
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 callbackSO (qint16 *buf, qint32 len, unsigned int channel=0)
 
void callbackMO (qint16 *buf, qint32 samplesPerChannel)
 

Private Attributes

QMutex m_startWaitMutex
 
QWaitCondition m_startWaiter
 
bool m_running
 
struct bladerf * m_dev
 
Channelm_channels
 Array of channels dynamically allocated for the given number of Tx channels. More...
 
qint16 * m_buf
 Full buffer for SISO or MIMO operation. More...
 
unsigned int m_nbChannels
 

Detailed Description

Definition at line 31 of file bladerf2outputthread.h.

Constructor & Destructor Documentation

◆ BladeRF2OutputThread()

BladeRF2OutputThread::BladeRF2OutputThread ( struct bladerf *  dev,
unsigned int  nbTxChannels,
QObject *  parent = 0 
)

Definition at line 24 of file bladerf2outputthread.cpp.

References DeviceBladeRF2::blockSize, m_buf, and m_channels.

24  :
25  QThread(parent),
26  m_running(false),
27  m_dev(dev),
28  m_nbChannels(nbTxChannels)
29 {
30  qDebug("BladeRF2OutputThread::BladeRF2OutputThread");
31  m_channels = new Channel[nbTxChannels];
32  m_buf = new qint16[2*DeviceBladeRF2::blockSize*nbTxChannels];
33 }
static const unsigned int blockSize
Channel * m_channels
Array of channels dynamically allocated for the given number of Tx channels.
qint16 * m_buf
Full buffer for SISO or MIMO operation.

◆ ~BladeRF2OutputThread()

BladeRF2OutputThread::~BladeRF2OutputThread ( )

Definition at line 35 of file bladerf2outputthread.cpp.

References m_buf, m_channels, m_running, and stopWork().

36 {
37  qDebug("BladeRF2OutputThread::~BladeRF2OutputThread");
38 
39  if (m_running) {
40  stopWork();
41  }
42 
43  delete[] m_buf;
44  delete[] m_channels;
45 }
Channel * m_channels
Array of channels dynamically allocated for the given number of Tx channels.
qint16 * m_buf
Full buffer for SISO or MIMO operation.
+ Here is the call graph for this function:

Member Function Documentation

◆ callbackMO()

void BladeRF2OutputThread::callbackMO ( qint16 *  buf,
qint32  samplesPerChannel 
)
private

Definition at line 170 of file bladerf2outputthread.cpp.

References callbackSO(), m_channels, and m_nbChannels.

Referenced by run().

171 {
172  for (unsigned int channel = 0; channel < m_nbChannels; channel++)
173  {
174  if (m_channels[channel].m_sampleFifo) {
175  callbackSO(&buf[2*samplesPerChannel*channel], samplesPerChannel, channel);
176  } else {
177  std::fill(&buf[2*samplesPerChannel*channel], &buf[2*samplesPerChannel*channel]+2*samplesPerChannel, 0); // fill with zero samples
178  }
179  }
180 
181  // TODO: write a set of interpolators that can write interleaved samples in output directly
182  int status = bladerf_interleave_stream_buffer(BLADERF_TX_X2, BLADERF_FORMAT_SC16_Q11 , samplesPerChannel*m_nbChannels, (void *) buf);
183 
184  if (status < 0)
185  {
186  qCritical("BladeRF2OutputThread::callbackMI: cannot interleave buffer: %s", bladerf_strerror(status));
187  return;
188  }
189 }
void callbackSO(qint16 *buf, qint32 len, unsigned int channel=0)
Channel * m_channels
Array of channels dynamically allocated for the given number of Tx channels.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ callbackSO()

void BladeRF2OutputThread::callbackSO ( qint16 *  buf,
qint32  len,
unsigned int  channel = 0 
)
private

Definition at line 192 of file bladerf2outputthread.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, BladeRF2OutputThread::Channel::m_interpolators, BladeRF2OutputThread::Channel::m_sampleFifo, and SampleSourceFifo::readAdvance().

Referenced by callbackMO(), and run().

193 {
194  if (m_channels[channel].m_sampleFifo)
195  {
196  float bal = m_channels[channel].m_sampleFifo->getRWBalance();
197 
198  if (bal < -0.25) {
199  qDebug("BladeRF2OutputThread::callbackSO: read lags: %f", bal);
200  } else if (bal > 0.25) {
201  qDebug("BladeRF2OutputThread::callbackSO: read leads: %f", bal);
202  }
203 
204  SampleVector::iterator beginRead;
205  m_channels[channel].m_sampleFifo->readAdvance(beginRead, len/(1<<m_channels[channel].m_log2Interp));
206  beginRead -= len;
207 
208  if (m_channels[channel].m_log2Interp == 0)
209  {
210  m_channels[channel].m_interpolators.interpolate1(&beginRead, buf, len*2);
211  }
212  else
213  {
214  switch (m_channels[channel].m_log2Interp)
215  {
216  case 1:
217  m_channels[channel].m_interpolators.interpolate2_cen(&beginRead, buf, len*2);
218  break;
219  case 2:
220  m_channels[channel].m_interpolators.interpolate4_cen(&beginRead, buf, len*2);
221  break;
222  case 3:
223  m_channels[channel].m_interpolators.interpolate8_cen(&beginRead, buf, len*2);
224  break;
225  case 4:
226  m_channels[channel].m_interpolators.interpolate16_cen(&beginRead, buf, len*2);
227  break;
228  case 5:
229  m_channels[channel].m_interpolators.interpolate32_cen(&beginRead, buf, len*2);
230  break;
231  case 6:
232  m_channels[channel].m_interpolators.interpolate64_cen(&beginRead, buf, len*2);
233  break;
234  default:
235  break;
236  }
237  }
238  }
239  else
240  {
241  std::fill(buf, buf+2*len, 0);
242  }
243 }
void interpolate64_cen(SampleVector::iterator *it, T *buf, qint32 len, bool invertIQ=false)
float getRWBalance() const
Channel * m_channels
Array of channels dynamically allocated for the given number of Tx channels.
void interpolate32_cen(SampleVector::iterator *it, T *buf, qint32 len, bool invertIQ=false)
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)
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)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getFifo()

SampleSourceFifo * BladeRF2OutputThread::getFifo ( unsigned int  channel)

Definition at line 161 of file bladerf2outputthread.cpp.

References m_channels, m_nbChannels, and BladeRF2OutputThread::Channel::m_sampleFifo.

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

162 {
163  if (channel < m_nbChannels) {
164  return m_channels[channel].m_sampleFifo;
165  } else {
166  return 0;
167  }
168 }
Channel * m_channels
Array of channels dynamically allocated for the given number of Tx channels.
+ Here is the caller graph for this function:

◆ getLog2Interpolation()

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

Definition at line 145 of file bladerf2outputthread.cpp.

References m_channels, BladeRF2OutputThread::Channel::m_log2Interp, and m_nbChannels.

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

146 {
147  if (channel < m_nbChannels) {
148  return m_channels[channel].m_log2Interp;
149  } else {
150  return 0;
151  }
152 }
Channel * m_channels
Array of channels dynamically allocated for the given number of Tx channels.
+ Here is the caller graph for this function:

◆ getNbChannels()

unsigned int BladeRF2OutputThread::getNbChannels ( ) const
inline

Definition at line 41 of file bladerf2outputthread.h.

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

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

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

◆ getNbFifos()

unsigned int BladeRF2OutputThread::getNbFifos ( )
private

Definition at line 124 of file bladerf2outputthread.cpp.

References i, m_channels, and m_nbChannels.

Referenced by run().

125 {
126  unsigned int fifoCount = 0;
127 
128  for (unsigned int i = 0; i < m_nbChannels; i++)
129  {
130  if (m_channels[i].m_sampleFifo) {
131  fifoCount++;
132  }
133  }
134 
135  return fifoCount;
136 }
Channel * m_channels
Array of channels dynamically allocated for the given number of Tx channels.
int32_t i
Definition: decimators.h:244
+ Here is the caller graph for this function:

◆ isRunning()

bool BladeRF2OutputThread::isRunning ( ) const
inline

Definition at line 40 of file bladerf2outputthread.h.

References m_running.

40 { return m_running; }

◆ run()

void BladeRF2OutputThread::run ( )
private

Definition at line 65 of file bladerf2outputthread.cpp.

References DeviceBladeRF2::blockSize, callbackMO(), callbackSO(), getNbFifos(), m_buf, m_dev, m_nbChannels, m_running, and m_startWaiter.

66 {
67  int res;
68 
69  m_running = true;
70  m_startWaiter.wakeAll();
71 
72  unsigned int nbFifos = getNbFifos();
73 
74  if ((m_nbChannels > 0) && (nbFifos > 0))
75  {
76  int status;
77 
78  if (m_nbChannels > 1) {
79  status = bladerf_sync_config(m_dev, BLADERF_TX_X2, BLADERF_FORMAT_SC16_Q11, 128, 16384, 32, 1500);
80  } else {
81  status = bladerf_sync_config(m_dev, BLADERF_TX_X1, BLADERF_FORMAT_SC16_Q11, 64, 8192, 32, 1500);
82  }
83 
84  if (status < 0)
85  {
86  qCritical("BladeRF2OutputThread::run: cannot configure streams: %s", bladerf_strerror(status));
87  }
88  else
89  {
90  qDebug("BladeRF2OutputThread::run: start running loop");
91 
92  while (m_running)
93  {
94  if (m_nbChannels > 1)
95  {
97  res = bladerf_sync_tx(m_dev, m_buf, DeviceBladeRF2::blockSize*m_nbChannels, 0, 1500);
98  }
99  else
100  {
102  res = bladerf_sync_tx(m_dev, m_buf, DeviceBladeRF2::blockSize, 0, 1500);
103  }
104 
105  if (res < 0)
106  {
107  qCritical("BladeRF2OutputThread::run sync Rx error: %s", bladerf_strerror(res));
108  break;
109  }
110  }
111 
112  qDebug("BladeRF2OutputThread::run: stop running loop");
113  }
114  }
115  else
116  {
117  qWarning("BladeRF2OutputThread::run: no channels or FIFO allocated. Aborting");
118  }
119 
120 
121  m_running = false;
122 }
void callbackSO(qint16 *buf, qint32 len, unsigned int channel=0)
void callbackMO(qint16 *buf, qint32 samplesPerChannel)
static const unsigned int blockSize
QWaitCondition m_startWaiter
qint16 * m_buf
Full buffer for SISO or MIMO operation.
+ Here is the call graph for this function:

◆ setFifo()

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

Definition at line 154 of file bladerf2outputthread.cpp.

References m_channels, m_nbChannels, and BladeRF2OutputThread::Channel::m_sampleFifo.

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

155 {
156  if (channel < m_nbChannels) {
157  m_channels[channel].m_sampleFifo = sampleFifo;
158  }
159 }
Channel * m_channels
Array of channels dynamically allocated for the given number of Tx channels.
+ Here is the caller graph for this function:

◆ setLog2Interpolation()

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

Definition at line 138 of file bladerf2outputthread.cpp.

References m_channels, BladeRF2OutputThread::Channel::m_log2Interp, and m_nbChannels.

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

139 {
140  if (channel < m_nbChannels) {
141  m_channels[channel].m_log2Interp = log2_interp;
142  }
143 }
Channel * m_channels
Array of channels dynamically allocated for the given number of Tx channels.
+ Here is the caller graph for this function:

◆ startWork()

void BladeRF2OutputThread::startWork ( )

Definition at line 47 of file bladerf2outputthread.cpp.

References m_running, m_startWaiter, and m_startWaitMutex.

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

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

◆ stopWork()

void BladeRF2OutputThread::stopWork ( )

Definition at line 59 of file bladerf2outputthread.cpp.

References m_running.

Referenced by BladeRF2Output::start(), BladeRF2Output::stop(), and ~BladeRF2OutputThread().

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

Member Data Documentation

◆ m_buf

qint16* BladeRF2OutputThread::m_buf
private

Full buffer for SISO or MIMO operation.

Definition at line 69 of file bladerf2outputthread.h.

Referenced by BladeRF2OutputThread(), run(), and ~BladeRF2OutputThread().

◆ m_channels

Channel* BladeRF2OutputThread::m_channels
private

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

Definition at line 68 of file bladerf2outputthread.h.

Referenced by BladeRF2OutputThread(), callbackMO(), callbackSO(), getFifo(), getLog2Interpolation(), getNbFifos(), setFifo(), setLog2Interpolation(), and ~BladeRF2OutputThread().

◆ m_dev

struct bladerf* BladeRF2OutputThread::m_dev
private

Definition at line 66 of file bladerf2outputthread.h.

Referenced by run().

◆ m_nbChannels

unsigned int BladeRF2OutputThread::m_nbChannels
private

◆ m_running

bool BladeRF2OutputThread::m_running
private

Definition at line 65 of file bladerf2outputthread.h.

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

◆ m_startWaiter

QWaitCondition BladeRF2OutputThread::m_startWaiter
private

Definition at line 64 of file bladerf2outputthread.h.

Referenced by run(), and startWork().

◆ m_startWaitMutex

QMutex BladeRF2OutputThread::m_startWaitMutex
private

Definition at line 63 of file bladerf2outputthread.h.

Referenced by startWork().


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