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.
udpsink.h
Go to the documentation of this file.
1 // Copyright (C) 2015 F4EXB //
3 // written by Edouard Griffiths //
4 // //
5 // This program is free software; you can redistribute it and/or modify //
6 // it under the terms of the GNU General Public License as published by //
7 // the Free Software Foundation as version 3 of the License, or //
8 // (at your option) any later version. //
9 // //
10 // This program is distributed in the hope that it will be useful, //
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
13 // GNU General Public License V3 for more details. //
14 // //
15 // You should have received a copy of the GNU General Public License //
16 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
18 
19 #ifndef INCLUDE_UDPSRC_H
20 #define INCLUDE_UDPSRC_H
21 
22 #include <QMutex>
23 #include <QHostAddress>
24 #include <QNetworkRequest>
25 
26 #include "dsp/basebandsamplesink.h"
27 #include "channel/channelapi.h"
28 #include "dsp/nco.h"
29 #include "dsp/fftfilt.h"
30 #include "dsp/interpolator.h"
31 #include "dsp/phasediscri.h"
32 #include "dsp/movingaverage.h"
33 #include "dsp/agc.h"
34 #include "dsp/bandpass.h"
35 #include "util/udpsinkutil.h"
36 #include "util/message.h"
37 #include "audio/audiofifo.h"
38 
39 #include "udpsinksettings.h"
40 
41 class QNetworkAccessManager;
42 class QNetworkReply;
43 class QUdpSocket;
44 class DeviceAPI;
46 class DownChannelizer;
47 
48 class UDPSink : public BasebandSampleSink, public ChannelAPI {
49  Q_OBJECT
50 
51 public:
52  class MsgConfigureUDPSource : public Message {
54 
55  public:
56  const UDPSinkSettings& getSettings() const { return m_settings; }
57  bool getForce() const { return m_force; }
58 
59  static MsgConfigureUDPSource* create(const UDPSinkSettings& settings, bool force)
60  {
61  return new MsgConfigureUDPSource(settings, force);
62  }
63 
64  private:
66  bool m_force;
67 
68  MsgConfigureUDPSource(const UDPSinkSettings& settings, bool force) :
69  Message(),
70  m_settings(settings),
71  m_force(force)
72  {
73  }
74  };
75 
78 
79  public:
80  int getSampleRate() const { return m_sampleRate; }
81  int getCenterFrequency() const { return m_centerFrequency; }
82 
83  static MsgConfigureChannelizer* create(int sampleRate, int centerFrequency)
84  {
85  return new MsgConfigureChannelizer(sampleRate, centerFrequency);
86  }
87 
88  private:
91 
92  MsgConfigureChannelizer(int sampleRate, int centerFrequency) :
93  Message(),
94  m_sampleRate(sampleRate),
95  m_centerFrequency(centerFrequency)
96  { }
97  };
98 
99  UDPSink(DeviceAPI *deviceAPI);
100  virtual ~UDPSink();
101  virtual void destroy() { delete this; }
102  void setSpectrum(BasebandSampleSink* spectrum) { m_spectrum = spectrum; }
103 
104  void setSpectrum(MessageQueue* messageQueue, bool enabled);
105  double getMagSq() const { return m_magsq; }
106  double getInMagSq() const { return m_inMagsq; }
107  bool getSquelchOpen() const { return m_squelchOpen; }
108 
109  virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly);
110  virtual void start();
111  virtual void stop();
112  virtual bool handleMessage(const Message& cmd);
113 
114  virtual void getIdentifier(QString& id) { id = objectName(); }
115  virtual void getTitle(QString& title) { title = m_settings.m_title; }
116  virtual qint64 getCenterFrequency() const { return m_settings.m_inputFrequencyOffset; }
117 
118  virtual QByteArray serialize() const;
119  virtual bool deserialize(const QByteArray& data);
120 
121  virtual int getNbSinkStreams() const { return 1; }
122  virtual int getNbSourceStreams() const { return 0; }
123 
124  virtual qint64 getStreamCenterFrequency(int streamIndex, bool sinkElseSource) const
125  {
126  (void) streamIndex;
127  (void) sinkElseSource;
129  }
130 
131  virtual int webapiSettingsGet(
133  QString& errorMessage);
134 
135  virtual int webapiSettingsPutPatch(
136  bool force,
137  const QStringList& channelSettingsKeys,
139  QString& errorMessage);
140 
141  virtual int webapiReportGet(
143  QString& errorMessage);
144 
145  static const QString m_channelIdURI;
146  static const QString m_channelId;
147  static const int udpBlockSize = 512; // UDP block size in number of bytes
148 
149 public slots:
150  void audioReadyRead();
151 
152 private slots:
153  void networkManagerFinished(QNetworkReply *reply);
154 
155 protected:
156  class MsgUDPSinkSpectrum : public Message {
158 
159  public:
160  bool getEnabled() const { return m_enabled; }
161 
162  static MsgUDPSinkSpectrum* create(bool enabled)
163  {
164  return new MsgUDPSinkSpectrum(enabled);
165  }
166 
167  private:
168  bool m_enabled;
169 
170  MsgUDPSinkSpectrum(bool enabled) :
171  Message(),
172  m_enabled(enabled)
173  { }
174  };
175 
176  struct Sample16
177  {
178  Sample16() : m_r(0), m_i(0) {}
179  Sample16(int16_t r, int16_t i) : m_r(r), m_i(i) {}
182  };
183 
184  struct Sample24
185  {
186  Sample24() : m_r(0), m_i(0) {}
187  Sample24(int32_t r, int32_t i) : m_r(r), m_i(i) {}
190  };
191 
195 
199 
200  QUdpSocket *m_audioSocket;
201 
202  double m_magsq;
203  double m_inMagsq;
207 
210 
215 
220 
224 
227 
228  quint32 m_nextSSBId;
229  quint32 m_nextS16leId;
230 
232  static const int m_udpAudioPayloadSize = 8192;
233  static const Real m_agcTarget;
234 
236 
237  double m_squelch;
243 
246 
247  QNetworkAccessManager *m_networkManager;
248  QNetworkRequest m_networkRequest;
249 
251 
252  void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force = true);
253  void applySettings(const UDPSinkSettings& settings, bool force = false);
254 
257  void webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const UDPSinkSettings& settings, bool force);
258 
259  inline void calculateSquelch(double value)
260  {
261  if ((!m_settings.m_squelchEnabled) || (value > m_squelch))
262  {
263  if (m_squelchGate == 0)
264  {
265  m_squelchOpen = true;
266  }
267  else
268  {
269  if (m_squelchOpenCount < m_squelchGate)
270  {
271  m_squelchOpenCount++;
272  }
273  else
274  {
275  m_squelchCloseCount = m_squelchRelease;
276  m_squelchOpen = true;
277  }
278  }
279  }
280  else
281  {
282  if (m_squelchGate == 0)
283  {
284  m_squelchOpen = false;
285  }
286  else
287  {
288  if (m_squelchCloseCount > 0)
289  {
290  m_squelchCloseCount--;
291  }
292  else
293  {
294  m_squelchOpenCount = 0;
295  m_squelchOpen = false;
296  }
297  }
298  }
299  }
300 
301  inline void initSquelch(bool open)
302  {
303  if (open)
304  {
305  m_squelchOpen = true;
306  m_squelchOpenCount = m_squelchGate;
307  m_squelchCloseCount = m_squelchRelease;
308  }
309  else
310  {
311  m_squelchOpen = false;
312  m_squelchOpenCount = 0;
313  m_squelchCloseCount = 0;
314  }
315  }
316 
317  void udpWrite(FixReal real, FixReal imag)
318  {
319  if (SDR_RX_SAMP_SZ == 16)
320  {
321  if (m_settings.m_sampleFormat == UDPSinkSettings::FormatIQ16) {
322  m_udpBuffer16->write(Sample16(real, imag));
323  } else if (m_settings.m_sampleFormat == UDPSinkSettings::FormatIQ24) {
324  m_udpBuffer24->write(Sample24(real<<8, imag<<8));
325  } else {
326  m_udpBuffer16->write(Sample16(real, imag));
327  }
328  }
329  else if (SDR_RX_SAMP_SZ == 24)
330  {
331  if (m_settings.m_sampleFormat == UDPSinkSettings::FormatIQ16) {
332  m_udpBuffer16->write(Sample16(real>>8, imag>>8));
333  } else if (m_settings.m_sampleFormat == UDPSinkSettings::FormatIQ24) {
334  m_udpBuffer24->write(Sample24(real, imag));
335  } else {
336  m_udpBuffer16->write(Sample16(real>>8, imag>>8));
337  }
338  }
339  }
340 
341  void udpWriteMono(FixReal sample)
342  {
343  if (SDR_RX_SAMP_SZ == 16)
344  {
345  m_udpBufferMono16->write(sample);
346  }
347  else if (SDR_RX_SAMP_SZ == 24)
348  {
349  m_udpBufferMono16->write(sample>>8);
350  }
351  }
352 
353  void udpWriteNorm(Real real, Real imag)
354  {
355  m_udpBuffer16->write(Sample16(real*32768.0, imag*32768.0));
356  }
357 
358  void udpWriteNormMono(Real sample)
359  {
360  m_udpBufferMono16->write(sample*32768.0);
361  }
362 
363 };
364 
365 #endif // INCLUDE_UDPSRC_H
static MsgConfigureChannelizer * create(int sampleRate, int centerFrequency)
Definition: udpsink.h:83
short int16_t
Definition: rtptypes_win.h:43
uint m_audioBufferFill
Definition: udpsink.h:222
static const QString m_channelId
Definition: udpsink.h:146
const UDPSinkSettings & getSettings() const
Definition: udpsink.h:56
std::vector< Sample > SampleVector
Definition: dsptypes.h:96
std::vector< AudioSample > AudioVector
Definition: dsptypes.h:98
MsgUDPSinkSpectrum(bool enabled)
Definition: udpsink.h:170
DownChannelizer * m_channelizer
Definition: udpsink.h:194
MsgConfigureUDPSource(const UDPSinkSettings &settings, bool force)
Definition: udpsink.h:68
bool getSquelchOpen() const
Definition: udpsink.h:107
Complex m_last
Definition: udpsink.h:209
virtual void getIdentifier(QString &id)
Definition: udpsink.h:114
virtual bool deserialize(const QByteArray &data)
Definition: udpsink.cpp:703
double m_inMagsq
Definition: udpsink.h:203
virtual void destroy()
Definition: udpsink.h:101
void udpWriteNorm(Real real, Real imag)
Definition: udpsink.h:353
Real m_scale
Definition: udpsink.h:208
virtual int webapiSettingsPutPatch(bool force, const QStringList &channelSettingsKeys, SWGSDRangel::SWGChannelSettings &response, QString &errorMessage)
Definition: udpsink.cpp:731
int m_squelchOpenCount
Definition: udpsink.h:239
void udpWrite(FixReal real, FixReal imag)
Definition: udpsink.h:317
virtual bool handleMessage(const Message &cmd)
Processing of a message. Returns true if message has actually been processed.
Definition: udpsink.cpp:342
Definition: agc.h:36
quint32 m_nextSSBId
Definition: udpsink.h:228
bool m_spectrumEnabled
Definition: udpsink.h:226
UDPSinkSettings m_settings
Definition: udpsink.h:65
void calculateSquelch(double value)
Definition: udpsink.h:259
UDPSinkSettings m_settings
Definition: udpsink.h:198
MovingAverage< double > m_amMovingAverage
Definition: udpsink.h:206
void write(T sample)
Definition: udpsinkutil.h:92
SampleVector m_sampleBuffer
Definition: udpsink.h:216
void setSpectrum(BasebandSampleSink *spectrum)
Definition: udpsink.h:102
double getInMagSq() const
Definition: udpsink.h:106
virtual int getNbSinkStreams() const
Definition: udpsink.h:121
bool getEnabled() const
Definition: udpsink.h:160
static const int m_udpAudioPayloadSize
UDP audio samples buffer. No UDP block on Earth is larger than this.
Definition: udpsink.h:232
MagAGC m_agc
Definition: udpsink.h:244
static const Real m_agcTarget
Definition: udpsink.h:233
AudioVector m_audioBuffer
Definition: udpsink.h:221
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force=true)
Definition: udpsink.cpp:472
double m_magsq
Definition: udpsink.h:202
#define SDR_RX_SAMP_SZ
Definition: dsptypes.h:32
BasebandSampleSink * m_spectrum
Definition: udpsink.h:225
virtual int webapiReportGet(SWGSDRangel::SWGChannelReport &response, QString &errorMessage)
Definition: udpsink.cpp:839
MovingAverage< double > m_outMovingAverage
Definition: udpsink.h:204
void webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings &response, const UDPSinkSettings &settings)
Definition: udpsink.cpp:850
void networkManagerFinished(QNetworkReply *reply)
Definition: udpsink.cpp:993
Definition: nco.h:25
double getMagSq() const
Definition: udpsink.h:105
AudioFifo m_audioFifo
Definition: udpsink.h:223
void udpWriteMono(FixReal sample)
Definition: udpsink.h:341
virtual QByteArray serialize() const
Definition: udpsink.cpp:698
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport &response)
Definition: udpsink.cpp:896
QNetworkAccessManager * m_networkManager
Definition: udpsink.h:247
NCO m_nco
Definition: udpsink.h:211
Sample16(int16_t r, int16_t i)
Definition: udpsink.h:179
UDPSinkUtil< int16_t > * m_udpBufferMono16
Definition: udpsink.h:218
#define MESSAGE_CLASS_DECLARATION
Definition: message.h:43
virtual void getTitle(QString &title)
Definition: udpsink.h:115
ThreadedBasebandSampleSink * m_threadedChannelizer
Definition: udpsink.h:193
Bandpass< double > m_bandpass
Definition: udpsink.h:245
QUdpSocket * m_audioSocket
Definition: udpsink.h:200
int32_t i
Definition: decimators.h:244
virtual void stop()
Definition: udpsink.cpp:338
virtual qint64 getStreamCenterFrequency(int streamIndex, bool sinkElseSource) const
Definition: udpsink.h:124
virtual void feed(const SampleVector::const_iterator &begin, const SampleVector::const_iterator &end, bool positiveOnly)
Definition: udpsink.cpp:145
int int32_t
Definition: rtptypes_win.h:45
int m_inputFrequencyOffset
Definition: udpsink.h:197
Interpolator m_interpolator
Definition: udpsink.h:212
int m_squelchGate
number of samples computed from given gate
Definition: udpsink.h:241
void udpWriteNormMono(Real sample)
Definition: udpsink.h:358
int m_squelchRelease
Definition: udpsink.h:242
virtual int getNbSourceStreams() const
Definition: udpsink.h:122
virtual int webapiSettingsGet(SWGSDRangel::SWGChannelSettings &response, QString &errorMessage)
Definition: udpsink.cpp:720
fftfilt * UDPFilter
Definition: udpsink.h:214
static const int udpBlockSize
Definition: udpsink.h:147
UDPSinkUtil< Sample16 > * m_udpBuffer16
Definition: udpsink.h:217
SampleFormat m_sampleFormat
QMutex m_settingsMutex
Definition: udpsink.h:250
UDPSink(DeviceAPI *deviceAPI)
Definition: udpsink.cpp:48
void webapiReverseSendSettings(QList< QString > &channelSettingsKeys, const UDPSinkSettings &settings, bool force)
Definition: udpsink.cpp:904
virtual ~UDPSink()
Definition: udpsink.cpp:122
QNetworkRequest m_networkRequest
Definition: udpsink.h:248
Real m_sampleDistanceRemain
Definition: udpsink.h:213
UDPSinkUtil< Sample24 > * m_udpBuffer24
Definition: udpsink.h:219
PhaseDiscriminators m_phaseDiscri
Definition: udpsink.h:235
char * m_udpAudioBuf
Definition: udpsink.h:231
void applySettings(const UDPSinkSettings &settings, bool force=false)
Definition: udpsink.cpp:496
virtual void start()
Definition: udpsink.cpp:332
int64_t m_inputFrequencyOffset
MovingAverage< double > m_inMovingAverage
Definition: udpsink.h:205
MsgConfigureChannelizer(int sampleRate, int centerFrequency)
Definition: udpsink.h:92
static MsgUDPSinkSpectrum * create(bool enabled)
Definition: udpsink.h:162
int m_inputSampleRate
Definition: udpsink.h:196
static const QString m_channelIdURI
Definition: udpsink.h:145
std::complex< Real > Complex
Definition: dsptypes.h:43
quint32 m_nextS16leId
Definition: udpsink.h:229
static MsgConfigureUDPSource * create(const UDPSinkSettings &settings, bool force)
Definition: udpsink.h:59
int m_squelchCloseCount
Definition: udpsink.h:240
bool m_squelchOpen
Definition: udpsink.h:238
float Real
Definition: dsptypes.h:42
void audioReadyRead()
Definition: udpsink.cpp:404
qint16 FixReal
Definition: dsptypes.h:35
void initSquelch(bool open)
Definition: udpsink.h:301
Complex m_this
Definition: udpsink.h:209
double m_squelch
Definition: udpsink.h:237
Sample24(int32_t r, int32_t i)
Definition: udpsink.h:187
DeviceAPI * m_deviceAPI
Definition: udpsink.h:192
virtual qint64 getCenterFrequency() const
Applies to a default stream.
Definition: udpsink.h:116