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.
limesdrinputthread.cpp
Go to the documentation of this file.
1 // Copyright (C) 2017 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 <errno.h>
19 #include <algorithm>
20 
21 #include "limesdrinputsettings.h"
22 #include "limesdrinputthread.h"
23 
24 LimeSDRInputThread::LimeSDRInputThread(lms_stream_t* stream, SampleSinkFifo* sampleFifo, QObject* parent) :
25  QThread(parent),
26  m_running(false),
27  m_stream(stream),
28  m_convertBuffer(LIMESDR_BLOCKSIZE),
29  m_sampleFifo(sampleFifo),
30  m_log2Decim(0)
31 {
32  std::fill(m_buf, m_buf + 2*LIMESDR_BLOCKSIZE, 0);
33 }
34 
36 {
37  stopWork();
38 }
39 
41 {
42  if (m_running) return; // return if running already
43 
44  if (LMS_StartStream(m_stream) < 0) {
45  qCritical("LimeSDRInputThread::startWork: could not start stream");
46  } else {
47  usleep(50000);
48  qDebug("LimeSDRInputThread::startWork: stream started");
49  }
50 
51  m_startWaitMutex.lock();
52  start();
53  while(!m_running)
54  m_startWaiter.wait(&m_startWaitMutex, 100);
55  m_startWaitMutex.unlock();
56 }
57 
59 {
60  if (!m_running) return; // return if not running
61 
62  m_running = false;
63  wait();
64 
65  if (LMS_StopStream(m_stream) < 0) {
66  qCritical("LimeSDRInputThread::stopWork: could not stop stream");
67  } else {
68  usleep(50000);
69  qDebug("LimeSDRInputThread::stopWork: stream stopped");
70  }
71 }
72 
73 void LimeSDRInputThread::setLog2Decimation(unsigned int log2_decim)
74 {
75  m_log2Decim = log2_decim;
76 }
77 
79 {
80  int res;
81 
82  lms_stream_meta_t metadata; //Use metadata for additional control over sample receive function behaviour
83  metadata.flushPartialPacket = false; //Do not discard data remainder when read size differs from packet size
84  metadata.waitForTimestamp = false; //Do not wait for specific timestamps
85 
86  m_running = true;
87  m_startWaiter.wakeAll();
88 
89  while (m_running)
90  {
91  if ((res = LMS_RecvStream(m_stream, (void *) m_buf, LIMESDR_BLOCKSIZE, &metadata, 1000)) < 0)
92  {
93  qCritical("LimeSDRInputThread::run read error: %s", strerror(errno));
94  break;
95  }
96 
97  callback(m_buf, 2 * res);
98  }
99 
100  m_running = false;
101 }
102 
103 // Decimate according to specified log2 (ex: log2=4 => decim=16)
104 void LimeSDRInputThread::callback(const qint16* buf, qint32 len)
105 {
106  SampleVector::iterator it = m_convertBuffer.begin();
107 
108  switch (m_log2Decim)
109  {
110  case 0:
111  m_decimators.decimate1(&it, buf, len);
112  break;
113  case 1:
114  m_decimators.decimate2_cen(&it, buf, len);
115  break;
116  case 2:
117  m_decimators.decimate4_cen(&it, buf, len);
118  break;
119  case 3:
120  m_decimators.decimate8_cen(&it, buf, len);
121  break;
122  case 4:
123  m_decimators.decimate16_cen(&it, buf, len);
124  break;
125  case 5:
126  m_decimators.decimate32_cen(&it, buf, len);
127  break;
128  case 6:
129  m_decimators.decimate64_cen(&it, buf, len);
130  break;
131  default:
132  break;
133  }
134 
135  m_sampleFifo->write(m_convertBuffer.begin(), it);
136 }
137 
void decimate64_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:3040
void decimate2_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:554
uint write(const quint8 *data, uint count)
QWaitCondition m_startWaiter
qint16 m_buf[2 *LIMESDR_BLOCKSIZE]
void decimate8_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:1057
virtual void startWork()
SampleSinkFifo * m_sampleFifo
void setLog2Decimation(unsigned int log2_decim)
LimeSDRInputThread(lms_stream_t *stream, SampleSinkFifo *sampleFifo, QObject *parent=0)
void decimate4_cen(SampleVector::iterator *it, const T *buf, qint32 len)
Definition: decimators.h:782
unsigned int m_log2Decim
Decimators< qint32, qint16, SDR_RX_SAMP_SZ, 12 > m_decimators
SampleVector m_convertBuffer
lms_stream_t * m_stream
void callback(const qint16 *buf, qint32 len)
#define LIMESDR_BLOCKSIZE
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