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.
sdrplayinput.cpp
Go to the documentation of this file.
1 // Copyright (C) 2016 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 <string.h>
19 #include <errno.h>
20 
21 #include <QDebug>
22 #include <QNetworkReply>
23 #include <QBuffer>
24 
25 #include "SWGDeviceSettings.h"
26 #include "SWGDeviceState.h"
27 #include "SWGDeviceReport.h"
28 #include "SWGSDRPlayReport.h"
29 
30 #include "util/simpleserializer.h"
31 #include "dsp/dspcommands.h"
32 #include "dsp/dspengine.h"
33 #include <dsp/filerecord.h>
34 #include "sdrplayinput.h"
35 
36 #include <device/deviceapi.h>
37 
38 #include "sdrplaythread.h"
39 
44 
46  m_deviceAPI(deviceAPI),
47  m_variant(SDRPlayUndef),
48  m_settings(),
49  m_dev(0),
50  m_sdrPlayThread(0),
51  m_deviceDescription("SDRPlay"),
52  m_devNumber(0),
53  m_running(false)
54 {
55  openDevice();
56  m_fileSink = new FileRecord(QString("test_%1.sdriq").arg(m_deviceAPI->getDeviceUID()));
57  m_deviceAPI->setNbSourceStreams(1);
58  m_deviceAPI->addAncillarySink(m_fileSink);
59 
60  m_networkManager = new QNetworkAccessManager();
61  connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
62 }
63 
65 {
66  disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
67  delete m_networkManager;
68 
69  if (m_running) {
70  stop();
71  }
72 
74  delete m_fileSink;
75  closeDevice();
76 }
77 
79 {
80  delete this;
81 }
82 
84 {
86 
87  if (m_dev != 0)
88  {
89  closeDevice();
90  }
91 
92  int res;
93  //int numberOfGains;
94 
95  if (!m_sampleFifo.setSize(96000 * 4))
96  {
97  qCritical("SDRPlayInput::openDevice: could not allocate SampleFifo");
98  return false;
99  }
100 
101  if ((res = mirisdr_open(&m_dev, MIRISDR_HW_SDRPLAY, m_devNumber)) < 0)
102  {
103  qCritical("SDRPlayInput::openDevice: could not open SDRPlay #%d: %s", m_devNumber, strerror(errno));
104  return false;
105  }
106 
107  char vendor[256];
108  char product[256];
109  char serial[256];
110 
111  vendor[0] = '\0';
112  product[0] = '\0';
113  serial[0] = '\0';
114 
115  if ((res = mirisdr_get_device_usb_strings(m_devNumber, vendor, product, serial)) < 0)
116  {
117  qCritical("SDRPlayInput::openDevice: error accessing USB device");
118  stop();
119  return false;
120  }
121 
122  qWarning("SDRPlayInput::openDevice: %s %s, SN: %s", vendor, product, serial);
123  m_deviceDescription = QString("%1 (SN %2)").arg(product).arg(serial);
124 
125  if (QString(product) == "RSP1A") {
127  } else if (QString(product) == "RSP2") {
129  } else {
131  }
132 
133  qDebug("SDRPlayInput::openDevice: m_variant: %d", (int) m_variant);
134 
135  return true;
136 }
137 
139 {
140 // QMutexLocker mutexLocker(&m_mutex);
141  int res;
142 
143  if (!m_dev) {
144  return false;
145  }
146 
147  if (m_running) stop();
148 
149  char s12FormatString[] = "336_S16";
150 
151  if ((res = mirisdr_set_sample_format(m_dev, s12FormatString))) // sample format S12
152  {
153  qCritical("SDRPlayInput::start: could not set sample format: rc: %d", res);
154  stop();
155  return false;
156  }
157 
159 
160  if ((res = mirisdr_set_sample_rate(m_dev, sampleRate)))
161  {
162  qCritical("SDRPlayInput::start: could not set sample rate to %d: rc: %d", sampleRate, res);
163  stop();
164  return false;
165  }
166 
167  char bulkFormatString[] = "BULK";
168 
169  if ((res = mirisdr_set_transfer(m_dev, bulkFormatString)) < 0)
170  {
171  qCritical("SDRPlayInput::start: could not set USB Bulk mode: rc: %d", res);
172  stop();
173  return false;
174  }
175 
176  if ((res = mirisdr_reset_buffer(m_dev)) < 0)
177  {
178  qCritical("SDRPlayInput::start: could not reset USB EP buffers: %s", strerror(errno));
179  stop();
180  return false;
181  }
182 
186 
188 
189 // mutexLocker.unlock();
190 
191  applySettings(m_settings, true, true);
192  m_running = true;
193 
194  return true;
195 }
196 
198 {
199  if (m_dev != 0)
200  {
201  mirisdr_close(m_dev);
202  m_dev = 0;
203  }
204 
205  m_deviceDescription.clear();
206 }
207 
209 {
210  applySettings(m_settings, true, true);
211 }
212 
214 {
215 // QMutexLocker mutexLocker(&m_mutex);
216 
217  if(m_sdrPlayThread != 0)
218  {
220  delete m_sdrPlayThread;
221  m_sdrPlayThread = 0;
222  }
223 
224  m_running = false;
225 }
226 
227 QByteArray SDRPlayInput::serialize() const
228 {
229  return m_settings.serialize();
230 }
231 
232 bool SDRPlayInput::deserialize(const QByteArray& data)
233 {
234  bool success = true;
235 
236  if (!m_settings.deserialize(data))
237  {
239  success = false;
240  }
241 
243  m_inputMessageQueue.push(message);
244 
245  if (m_guiMessageQueue)
246  {
248  m_guiMessageQueue->push(messageToGUI);
249  }
250 
251  return success;
252 }
253 
255 {
256  return m_deviceDescription;
257 }
258 
260 {
262  return rate / (1<<m_settings.m_log2Decim);
263 }
264 
266 {
268 }
269 
270 void SDRPlayInput::setCenterFrequency(qint64 centerFrequency)
271 {
272  SDRPlaySettings settings = m_settings;
273  settings.m_centerFrequency = centerFrequency;
274 
275  MsgConfigureSDRPlay* message = MsgConfigureSDRPlay::create(settings, false);
276  m_inputMessageQueue.push(message);
277 
278  if (m_guiMessageQueue)
279  {
280  MsgConfigureSDRPlay* messageToGUI = MsgConfigureSDRPlay::create(settings, false);
281  m_guiMessageQueue->push(messageToGUI);
282  }
283 }
284 
286 {
287  if (MsgConfigureSDRPlay::match(message))
288  {
289  MsgConfigureSDRPlay& conf = (MsgConfigureSDRPlay&) message;
290  qDebug() << "SDRPlayInput::handleMessage: MsgConfigureSDRPlay";
291  const SDRPlaySettings& settings = conf.getSettings();
292 
293  // change of sample rate needs full stop / start sequence that includes the standard apply settings
294  // only if in started state (iff m_dev != 0)
295  if ((m_dev != 0) && (m_settings.m_devSampleRateIndex != settings.m_devSampleRateIndex))
296  {
297  m_settings = settings;
298  stop();
299  start();
300  }
301  // standard changes
302  else
303  {
304  if (!applySettings(settings, false, conf.getForce()))
305  {
306  qDebug("SDRPlayInput::handleMessage: config error");
307  }
308  }
309 
310  return true;
311  }
312  else if (MsgFileRecord::match(message))
313  {
314  MsgFileRecord& conf = (MsgFileRecord&) message;
315  qDebug() << "SDRPlayInput::handleMessage: MsgFileRecord: " << conf.getStartStop();
316 
317  if (conf.getStartStop())
318  {
319  if (m_settings.m_fileRecordName.size() != 0) {
321  } else {
323  }
324 
326  }
327  else
328  {
330  }
331 
332  return true;
333  }
334  else if (MsgStartStop::match(message))
335  {
336  MsgStartStop& cmd = (MsgStartStop&) message;
337  qDebug() << "SDRPlayInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop");
338 
339  if (cmd.getStartStop())
340  {
342  {
344  }
345  }
346  else
347  {
349  }
350 
353  }
354 
355  return true;
356  }
357  else
358  {
359  return false;
360  }
361 }
362 
363 bool SDRPlayInput::applySettings(const SDRPlaySettings& settings, bool forwardChange, bool force)
364 {
365  bool forceGainSetting = false;
366  QList<QString> reverseAPIKeys;
367  QMutexLocker mutexLocker(&m_mutex);
368 
369  if ((m_settings.m_dcBlock != settings.m_dcBlock) || force)
370  {
371  reverseAPIKeys.append("dcBlock");
373  }
374 
375  if ((m_settings.m_iqCorrection != settings.m_iqCorrection) || force)
376  {
377  reverseAPIKeys.append("iqCorrection");
379  }
380 
381  // gains processing
382 
383  if ((m_settings.m_tunerGainMode != settings.m_tunerGainMode) || force)
384  {
385  reverseAPIKeys.append("tunerGainMode");
386  forceGainSetting = true;
387  }
388 
389  if ((m_settings.m_tunerGain != settings.m_tunerGain) || force) {
390  reverseAPIKeys.append("tunerGain");
391  }
392  if ((m_settings.m_lnaOn != settings.m_lnaOn) || force) {
393  reverseAPIKeys.append("lnaOn");
394  }
395 
396  if (settings.m_tunerGainMode) // auto
397  {
398  if ((m_settings.m_tunerGain != settings.m_tunerGain) || forceGainSetting)
399  {
400  if(m_dev != 0)
401  {
402  int r = mirisdr_set_tuner_gain(m_dev, settings.m_tunerGain);
403 
404  if (r < 0)
405  {
406  qDebug("SDRPlayInput::applySettings: could not set tuner gain");
407  }
408  else
409  {
410  int lnaGain;
411 
412  if (settings.m_frequencyBandIndex < 3) // bands using AM mode
413  {
414  lnaGain = mirisdr_get_mixbuffer_gain(m_dev);
415  }
416  else
417  {
418  lnaGain = mirisdr_get_lna_gain(m_dev);
419  }
420 
422  lnaGain,
423  mirisdr_get_mixer_gain(m_dev),
424  mirisdr_get_baseband_gain(m_dev),
425  mirisdr_get_tuner_gain(m_dev)
426  );
427 
428  if (getMessageQueueToGUI()) {
429  getMessageQueueToGUI()->push(message);
430  }
431  }
432  }
433  }
434  }
435  else // manual
436  {
437  bool anyChange = false;
438 
439  if ((m_settings.m_lnaOn != settings.m_lnaOn) || forceGainSetting)
440  {
441  if (m_dev != 0)
442  {
443  if (settings.m_frequencyBandIndex < 3) // bands using AM mode
444  {
445  int r = mirisdr_set_mixbuffer_gain(m_dev, settings.m_lnaOn ? 0 : 1); // mirisdr_set_mixbuffer_gain takes gain reduction
446 
447  if (r != 0) {
448  qDebug("SDRPlayInput::applySettings: could not set mixer buffer gain");
449  } else {
450  anyChange = true;
451  }
452  }
453  else
454  {
455  int r = mirisdr_set_lna_gain(m_dev, settings.m_lnaOn ? 0 : 1); // mirisdr_set_lna_gain takes gain reduction
456 
457  if (r != 0) {
458  qDebug("SDRPlayInput::applySettings: could not set LNA gain");
459  } else {
460  anyChange = true;
461  }
462  }
463  }
464  }
465 
466  if ((m_settings.m_mixerAmpOn != settings.m_mixerAmpOn) || forceGainSetting)
467  {
468  reverseAPIKeys.append("mixerAmpOn");
469 
470  if (m_dev != 0)
471  {
472  int r = mirisdr_set_mixer_gain(m_dev, settings.m_mixerAmpOn ? 0 : 1); // mirisdr_set_lna_gain takes gain reduction
473 
474  if (r != 0) {
475  qDebug("SDRPlayInput::applySettings: could not set mixer gain");
476  } else {
477  anyChange = true;
478  }
479  }
480  }
481 
482  if ((m_settings.m_basebandGain != settings.m_basebandGain) || forceGainSetting)
483  {
484  reverseAPIKeys.append("basebandGain");
485 
486  if (m_dev != 0)
487  {
488  int r = mirisdr_set_baseband_gain(m_dev, settings.m_basebandGain);
489 
490  if (r != 0) {
491  qDebug("SDRPlayInput::applySettings: could not set mixer gain");
492  } else {
493  anyChange = true;
494  }
495  }
496  }
497 
498  if (anyChange)
499  {
500  int lnaGain;
501 
502  if (settings.m_frequencyBandIndex < 3) { // bands using AM mode
503  lnaGain = mirisdr_get_mixbuffer_gain(m_dev);
504  } else {
505  lnaGain = mirisdr_get_lna_gain(m_dev);
506  }
507 
509  lnaGain,
510  mirisdr_get_mixer_gain(m_dev),
511  mirisdr_get_baseband_gain(m_dev),
512  mirisdr_get_tuner_gain(m_dev)
513  );
514 
515  if (getMessageQueueToGUI()) {
516  getMessageQueueToGUI()->push(message);
517  }
518  }
519  }
520 
521  if ((m_settings.m_log2Decim != settings.m_log2Decim) || force)
522  {
523  reverseAPIKeys.append("log2Decim");
524 
525  if (m_sdrPlayThread != 0)
526  {
528  qDebug() << "SDRPlayInput::applySettings: set decimation to " << (1<<settings.m_log2Decim);
529  }
530  }
531 
532  if ((m_settings.m_fcPos != settings.m_fcPos) || force)
533  {
534  reverseAPIKeys.append("fcPos");
535 
536  if (m_sdrPlayThread != 0)
537  {
538  m_sdrPlayThread->setFcPos((int) settings.m_fcPos);
539  qDebug() << "SDRPlayInput: set fc pos (enum) to " << (int) settings.m_fcPos;
540  }
541  }
542 
543  if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) {
544  reverseAPIKeys.append("centerFrequency");
545  }
546  if ((m_settings.m_LOppmTenths != settings.m_LOppmTenths) || force) {
547  reverseAPIKeys.append("LOppmTenths");
548  }
549 
551  || (m_settings.m_LOppmTenths != settings.m_LOppmTenths)
552  || (m_settings.m_fcPos != settings.m_fcPos)
553  || (m_settings.m_log2Decim != settings.m_log2Decim) || force)
554  {
555  qint64 deviceCenterFrequency = DeviceSampleSource::calculateDeviceCenterFrequency(
556  settings.m_centerFrequency,
557  0,
558  settings.m_log2Decim,
561  DeviceSampleSource::FrequencyShiftScheme::FSHIFT_STD,
562  false);
563 
564  forwardChange = true;
565 
566  if(m_dev != 0)
567  {
568  if (setDeviceCenterFrequency(deviceCenterFrequency)) {
569  qDebug() << "SDRPlayInput::applySettings: center freq: " << settings.m_centerFrequency << " Hz";
570  }
571  }
572  }
573 
574  if ((m_settings.m_bandwidthIndex != settings.m_bandwidthIndex) || force)
575  {
576  reverseAPIKeys.append("bandwidthIndex");
577  int bandwidth = SDRPlayBandwidths::getBandwidth(settings.m_bandwidthIndex);
578  int r = mirisdr_set_bandwidth(m_dev, bandwidth);
579 
580  if (r < 0) {
581  qCritical("SDRPlayInput::applySettings: set bandwidth %d failed: rc: %d", bandwidth, r);
582  } else {
583  qDebug("SDRPlayInput::applySettings: bandwidth set to %d", bandwidth);
584  }
585  }
586 
587  if ((m_settings.m_ifFrequencyIndex != settings.m_ifFrequencyIndex) || force)
588  {
589  reverseAPIKeys.append("ifFrequencyIndex");
590  int iFFrequency = SDRPlayIF::getIF(settings.m_ifFrequencyIndex);
591  int r = mirisdr_set_if_freq(m_dev, iFFrequency);
592 
593  if (r < 0) {
594  qCritical("SDRPlayInput::applySettings: set IF frequency to %d failed: rc: %d", iFFrequency, r);
595  } else {
596  qDebug("SDRPlayInput::applySettings: IF frequency set to %d", iFFrequency);
597  }
598  }
599 
600  if (settings.m_useReverseAPI)
601  {
602  bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) ||
606  webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force);
607  }
608 
609  m_settings = settings;
610 
611  if (forwardChange)
612  {
613  int sampleRate = getSampleRate();
615  m_fileSink->handleMessage(*notif); // forward to file sink
617  }
618 
619  return true;
620 }
621 
623 {
624  qint64 df = ((qint64)freq_hz * m_settings.m_LOppmTenths) / 10000000LL;
625  freq_hz += df;
626 
627  int r = mirisdr_set_center_freq(m_dev, static_cast<uint32_t>(freq_hz));
628 
629  if (r != 0)
630  {
631  qWarning("SDRPlayInput::setDeviceCenterFrequency: could not frequency to %llu Hz", freq_hz);
632  return false;
633  }
634  else
635  {
636  qWarning("SDRPlayInput::setDeviceCenterFrequency: frequency set to %llu Hz", freq_hz);
637  return true;
638  }
639 }
640 
642  SWGSDRangel::SWGDeviceState& response,
643  QString& errorMessage)
644 {
645  (void) errorMessage;
647  return 200;
648 }
649 
651  bool run,
652  SWGSDRangel::SWGDeviceState& response,
653  QString& errorMessage)
654 {
655  (void) errorMessage;
657  MsgStartStop *message = MsgStartStop::create(run);
658  m_inputMessageQueue.push(message);
659 
660  if (m_guiMessageQueue) // forward to GUI if any
661  {
662  MsgStartStop *msgToGUI = MsgStartStop::create(run);
663  m_guiMessageQueue->push(msgToGUI);
664  }
665 
666  return 200;
667 }
668 
671  QString& errorMessage)
672 {
673  (void) errorMessage;
675  response.getSdrPlaySettings()->init();
677  return 200;
678 }
679 
681  bool force,
682  const QStringList& deviceSettingsKeys,
683  SWGSDRangel::SWGDeviceSettings& response, // query + response
684  QString& errorMessage)
685 {
686  (void) errorMessage;
687  SDRPlaySettings settings = m_settings;
688 
689  if (deviceSettingsKeys.contains("centerFrequency")) {
691  }
692  if (deviceSettingsKeys.contains("tunerGain")) {
693  settings.m_tunerGain = response.getSdrPlaySettings()->getTunerGain();
694  }
695  if (deviceSettingsKeys.contains("LOppmTenths")) {
696  settings.m_LOppmTenths = response.getSdrPlaySettings()->getLOppmTenths();
697  }
698  if (deviceSettingsKeys.contains("frequencyBandIndex")) {
700  }
701  if (deviceSettingsKeys.contains("ifFrequencyIndex")) {
703  }
704  if (deviceSettingsKeys.contains("bandwidthIndex")) {
705  settings.m_bandwidthIndex = response.getSdrPlaySettings()->getBandwidthIndex();
706  }
707  if (deviceSettingsKeys.contains("devSampleRateIndex")) {
709  }
710  if (deviceSettingsKeys.contains("log2Decim")) {
711  settings.m_log2Decim = response.getSdrPlaySettings()->getLog2Decim();
712  }
713  if (deviceSettingsKeys.contains("fcPos"))
714  {
715  int fcPos = response.getSdrPlaySettings()->getFcPos();
716  fcPos = fcPos < 0 ? 0 : fcPos > 2 ? 2 : fcPos;
717  settings.m_fcPos = (SDRPlaySettings::fcPos_t) fcPos;
718  }
719  if (deviceSettingsKeys.contains("dcBlock")) {
720  settings.m_dcBlock = response.getSdrPlaySettings()->getDcBlock() != 0;
721  }
722  if (deviceSettingsKeys.contains("iqCorrection")) {
723  settings.m_iqCorrection = response.getSdrPlaySettings()->getIqCorrection() != 0;
724  }
725  if (deviceSettingsKeys.contains("tunerGainMode")) {
726  settings.m_tunerGainMode = response.getSdrPlaySettings()->getTunerGainMode() != 0;
727  }
728  if (deviceSettingsKeys.contains("lnaOn")) {
729  settings.m_lnaOn = response.getSdrPlaySettings()->getLnaOn() != 0;
730  }
731  if (deviceSettingsKeys.contains("mixerAmpOn")) {
732  settings.m_mixerAmpOn = response.getSdrPlaySettings()->getMixerAmpOn() != 0;
733  }
734  if (deviceSettingsKeys.contains("basebandGain")) {
735  settings.m_basebandGain = response.getSdrPlaySettings()->getBasebandGain();
736  }
737  if (deviceSettingsKeys.contains("fileRecordName")) {
738  settings.m_fileRecordName = *response.getSdrPlaySettings()->getFileRecordName();
739  }
740  if (deviceSettingsKeys.contains("useReverseAPI")) {
741  settings.m_useReverseAPI = response.getSdrPlaySettings()->getUseReverseApi() != 0;
742  }
743  if (deviceSettingsKeys.contains("reverseAPIAddress")) {
745  }
746  if (deviceSettingsKeys.contains("reverseAPIPort")) {
747  settings.m_reverseAPIPort = response.getSdrPlaySettings()->getReverseApiPort();
748  }
749  if (deviceSettingsKeys.contains("reverseAPIDeviceIndex")) {
751  }
752 
753  MsgConfigureSDRPlay *msg = MsgConfigureSDRPlay::create(settings, force);
755 
756  if (m_guiMessageQueue) // forward to GUI if any
757  {
758  MsgConfigureSDRPlay *msgToGUI = MsgConfigureSDRPlay::create(settings, force);
759  m_guiMessageQueue->push(msgToGUI);
760  }
761 
762  webapiFormatDeviceSettings(response, settings);
763  return 200;
764 }
765 
767 {
769  response.getSdrPlaySettings()->setTunerGain(settings.m_tunerGain);
770  response.getSdrPlaySettings()->setLOppmTenths(settings.m_LOppmTenths);
775  response.getSdrPlaySettings()->setLog2Decim(settings.m_log2Decim);
776  response.getSdrPlaySettings()->setFcPos((int) settings.m_fcPos);
777  response.getSdrPlaySettings()->setDcBlock(settings.m_dcBlock ? 1 : 0);
778  response.getSdrPlaySettings()->setIqCorrection(settings.m_iqCorrection ? 1 : 0);
779  response.getSdrPlaySettings()->setTunerGainMode((int) settings.m_tunerGainMode);
780  response.getSdrPlaySettings()->setLnaOn(settings.m_lnaOn ? 1 : 0);
781  response.getSdrPlaySettings()->setMixerAmpOn(settings.m_mixerAmpOn ? 1 : 0);
782  response.getSdrPlaySettings()->setBasebandGain(settings.m_basebandGain);
783 
784  if (response.getSdrPlaySettings()->getFileRecordName()) {
785  *response.getSdrPlaySettings()->getFileRecordName() = settings.m_fileRecordName;
786  } else {
787  response.getSdrPlaySettings()->setFileRecordName(new QString(settings.m_fileRecordName));
788  }
789 
790  response.getSdrPlaySettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
791 
792  if (response.getSdrPlaySettings()->getReverseApiAddress()) {
794  } else {
795  response.getSdrPlaySettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress));
796  }
797 
800 }
801 
804  QString& errorMessage)
805 {
806  (void) errorMessage;
808  response.getSdrPlayReport()->init();
809  webapiFormatDeviceReport(response);
810  return 200;
811 }
812 
814 {
815  response.getSdrPlayReport()->setSampleRates(new QList<SWGSDRangel::SWGSampleRate*>);
816 
817  for (unsigned int i = 0; i < SDRPlaySampleRates::getNbRates(); i++)
818  {
820  response.getSdrPlayReport()->getSampleRates()->back()->setRate(SDRPlaySampleRates::getRate(i));
821  }
822 
823  response.getSdrPlayReport()->setIntermediateFrequencies(new QList<SWGSDRangel::SWGFrequency*>);
824 
825  for (unsigned int i = 0; i < SDRPlayIF::getNbIFs(); i++)
826  {
828  response.getSdrPlayReport()->getIntermediateFrequencies()->back()->setFrequency(SDRPlayIF::getIF(i));
829  }
830 
831  response.getSdrPlayReport()->setBandwidths(new QList<SWGSDRangel::SWGBandwidth*>);
832 
833  for (unsigned int i = 0; i < SDRPlayBandwidths::getNbBandwidths(); i++)
834  {
835  response.getSdrPlayReport()->getBandwidths()->append(new SWGSDRangel::SWGBandwidth);
836  response.getSdrPlayReport()->getBandwidths()->back()->setBandwidth(SDRPlayBandwidths::getBandwidth(i));
837  }
838 
839  response.getSdrPlayReport()->setFrequencyBands(new QList<SWGSDRangel::SWGFrequencyBand*>);
840 
841  for (unsigned int i = 0; i < SDRPlayBands::getNbBands(); i++)
842  {
844  response.getSdrPlayReport()->getFrequencyBands()->back()->setName(new QString(SDRPlayBands::getBandName(i)));
845  response.getSdrPlayReport()->getFrequencyBands()->back()->setLowerBound(SDRPlayBands::getBandLow(i));
846  response.getSdrPlayReport()->getFrequencyBands()->back()->setHigherBound(SDRPlayBands::getBandHigh(i));
847  }
848 }
849 
850 void SDRPlayInput::webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const SDRPlaySettings& settings, bool force)
851 {
853  swgDeviceSettings->setDirection(0); // single Rx
854  swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
855  swgDeviceSettings->setDeviceHwType(new QString("SDRplay1"));
856  swgDeviceSettings->setSdrPlaySettings(new SWGSDRangel::SWGSDRPlaySettings());
857  SWGSDRangel::SWGSDRPlaySettings *swgSDRPlaySettings = swgDeviceSettings->getSdrPlaySettings();
858 
859  // transfer data that has been modified. When force is on transfer all data except reverse API data
860 
861  if (deviceSettingsKeys.contains("centerFrequency") || force) {
862  swgSDRPlaySettings->setCenterFrequency(settings.m_centerFrequency);
863  }
864  if (deviceSettingsKeys.contains("tunerGain") || force) {
865  swgSDRPlaySettings->setTunerGain(settings.m_tunerGain);
866  }
867  if (deviceSettingsKeys.contains("LOppmTenths") || force) {
868  swgSDRPlaySettings->setLOppmTenths(settings.m_LOppmTenths);
869  }
870  if (deviceSettingsKeys.contains("frequencyBandIndex") || force) {
871  swgSDRPlaySettings->setFrequencyBandIndex(settings.m_frequencyBandIndex);
872  }
873  if (deviceSettingsKeys.contains("ifFrequencyIndex") || force) {
874  swgSDRPlaySettings->setIfFrequencyIndex(settings.m_ifFrequencyIndex);
875  }
876  if (deviceSettingsKeys.contains("bandwidthIndex") || force) {
877  swgSDRPlaySettings->setBandwidthIndex(settings.m_bandwidthIndex);
878  }
879  if (deviceSettingsKeys.contains("devSampleRateIndex") || force) {
880  swgSDRPlaySettings->setDevSampleRateIndex(settings.m_devSampleRateIndex);
881  }
882  if (deviceSettingsKeys.contains("log2Decim") || force) {
883  swgSDRPlaySettings->setLog2Decim(settings.m_log2Decim);
884  }
885  if (deviceSettingsKeys.contains("fcPos") || force) {
886  swgSDRPlaySettings->setFcPos((int) settings.m_fcPos);
887  }
888  if (deviceSettingsKeys.contains("dcBlock") || force) {
889  swgSDRPlaySettings->setDcBlock(settings.m_dcBlock ? 1 : 0);
890  }
891  if (deviceSettingsKeys.contains("iqCorrection") || force) {
892  swgSDRPlaySettings->setIqCorrection(settings.m_iqCorrection ? 1 : 0);
893  }
894  if (deviceSettingsKeys.contains("tunerGainMode") || force) {
895  swgSDRPlaySettings->setTunerGainMode(settings.m_tunerGainMode ? 1 : 0);
896  }
897  if (deviceSettingsKeys.contains("lnaOn") || force) {
898  swgSDRPlaySettings->setLnaOn(settings.m_lnaOn ? 1 : 0);
899  }
900  if (deviceSettingsKeys.contains("mixerAmpOn") || force) {
901  swgSDRPlaySettings->setMixerAmpOn(settings.m_mixerAmpOn ? 1 : 0);
902  }
903  if (deviceSettingsKeys.contains("basebandGain") || force) {
904  swgSDRPlaySettings->setBasebandGain(settings.m_basebandGain);
905  }
906  if (deviceSettingsKeys.contains("fileRecordName") || force) {
907  swgSDRPlaySettings->setFileRecordName(new QString(settings.m_fileRecordName));
908  }
909 
910  QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings")
911  .arg(settings.m_reverseAPIAddress)
912  .arg(settings.m_reverseAPIPort)
913  .arg(settings.m_reverseAPIDeviceIndex);
914  m_networkRequest.setUrl(QUrl(deviceSettingsURL));
915  m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
916 
917  QBuffer *buffer=new QBuffer();
918  buffer->open((QBuffer::ReadWrite));
919  buffer->write(swgDeviceSettings->asJson().toUtf8());
920  buffer->seek(0);
921 
922  // Always use PATCH to avoid passing reverse API settings
923  m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer);
924 
925  delete swgDeviceSettings;
926 }
927 
929 {
931  swgDeviceSettings->setDirection(0); // single Rx
932  swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
933  swgDeviceSettings->setDeviceHwType(new QString("SDRplay1"));
934 
935  QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/run")
939  m_networkRequest.setUrl(QUrl(deviceSettingsURL));
940  m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
941 
942  QBuffer *buffer=new QBuffer();
943  buffer->open((QBuffer::ReadWrite));
944  buffer->write(swgDeviceSettings->asJson().toUtf8());
945  buffer->seek(0);
946 
947  if (start) {
948  m_networkManager->sendCustomRequest(m_networkRequest, "POST", buffer);
949  } else {
950  m_networkManager->sendCustomRequest(m_networkRequest, "DELETE", buffer);
951  }
952 
953  delete swgDeviceSettings;
954 }
955 
956 void SDRPlayInput::networkManagerFinished(QNetworkReply *reply)
957 {
958  QNetworkReply::NetworkError replyError = reply->error();
959 
960  if (replyError)
961  {
962  qWarning() << "SDRPlayInput::networkManagerFinished:"
963  << " error(" << (int) replyError
964  << "): " << replyError
965  << ": " << reply->errorString();
966  return;
967  }
968 
969  QString answer = reply->readAll();
970  answer.chop(1); // remove last \n
971  qDebug("SDRPlayInput::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
972 }
973 
974 // ====================================================================
975 
976 unsigned int SDRPlaySampleRates::m_rates[m_nb_rates] = {
977  1536000, // 0
978  1792000, // 1
979  2000000, // 2
980  2048000, // 3
981  2304000, // 4
982  2400000, // 5
983  3072000, // 6
984  3200000, // 7
985  4000000, // 8
986  4096000, // 9
987  4608000, // 10
988  4800000, // 11
989  5000000, // 12
990  6000000, // 13
991  6144000, // 14
992  6400000, // 15
993  8000000, // 16
994  8192000, // 17
995 };
996 
997 unsigned int SDRPlaySampleRates::getRate(unsigned int rate_index)
998 {
999  if (rate_index < m_nb_rates)
1000  {
1001  return m_rates[rate_index];
1002  }
1003  else
1004  {
1005  return m_rates[0];
1006  }
1007 }
1008 
1009 unsigned int SDRPlaySampleRates::getRateIndex(unsigned int rate)
1010 {
1011  for (unsigned int i=0; i < m_nb_rates; i++)
1012  {
1013  if (rate == m_rates[i])
1014  {
1015  return i;
1016  }
1017  }
1018 
1019  return 0;
1020 }
1021 
1023 {
1025 }
1026 
1027 // ====================================================================
1028 
1029 unsigned int SDRPlayBandwidths::m_bw[m_nb_bw] = {
1030  200000, // 0
1031  300000, // 1
1032  600000, // 2
1033  1536000, // 3
1034  5000000, // 4
1035  6000000, // 5
1036  7000000, // 6
1037  8000000, // 7
1038 };
1039 
1040 unsigned int SDRPlayBandwidths::getBandwidth(unsigned int bandwidth_index)
1041 {
1042  if (bandwidth_index < m_nb_bw)
1043  {
1044  return m_bw[bandwidth_index];
1045  }
1046  else
1047  {
1048  return m_bw[0];
1049  }
1050 }
1051 
1052 unsigned int SDRPlayBandwidths::getBandwidthIndex(unsigned int bandwidth)
1053 {
1054  for (unsigned int i=0; i < m_nb_bw; i++)
1055  {
1056  if (bandwidth == m_bw[i])
1057  {
1058  return i;
1059  }
1060  }
1061 
1062  return 0;
1063 }
1064 
1066 {
1068 }
1069 
1070 // ====================================================================
1071 
1072 unsigned int SDRPlayIF::m_if[m_nb_if] = {
1073  0, // 0
1074  450000, // 1
1075  1620000, // 2
1076  2048000, // 3
1077 };
1078 
1079 unsigned int SDRPlayIF::getIF(unsigned int if_index)
1080 {
1081  if (if_index < m_nb_if)
1082  {
1083  return m_if[if_index];
1084  }
1085  else
1086  {
1087  return m_if[0];
1088  }
1089 }
1090 
1091 unsigned int SDRPlayIF::getIFIndex(unsigned int iff)
1092 {
1093  for (unsigned int i=0; i < m_nb_if; i++)
1094  {
1095  if (iff == m_if[i])
1096  {
1097  return i;
1098  }
1099  }
1100 
1101  return 0;
1102 }
1103 
1104 unsigned int SDRPlayIF::getNbIFs()
1105 {
1106  return SDRPlayIF::m_nb_if;
1107 }
1108 
1109 // ====================================================================
1110 
1112 unsigned int SDRPlayBands::m_bandLow[m_nb_bands] = {
1113  10, // 0
1114  12000, // 1
1115  30000, // 2
1116  50000, // 3
1117  120000, // 4
1118  250000, // 5
1119  380000, // 6
1120  1000000, // 7
1121 };
1122 
1124 unsigned int SDRPlayBands::m_bandHigh[m_nb_bands] = {
1125  12000, // 0
1126  30000, // 1
1127  50000, // 2
1128  120000, // 3
1129  250000, // 4
1130  380000, // 5
1131  1000000, // 6
1132  2000000, // 7
1133 };
1134 
1135 const char* SDRPlayBands::m_bandName[m_nb_bands] = {
1136  "10k-12M", // 0
1137  "12-30M", // 1
1138  "30-50M", // 2
1139  "50-120M", // 3
1140  "120-250M", // 4
1141  "250-380M", // 5
1142  "380M-1G", // 6
1143  "1-2G", // 7
1144 };
1145 
1146 QString SDRPlayBands::getBandName(unsigned int band_index)
1147 {
1148  if (band_index < m_nb_bands)
1149  {
1150  return QString(m_bandName[band_index]);
1151  }
1152  else
1153  {
1154  return QString(m_bandName[0]);
1155  }
1156 }
1157 
1158 unsigned int SDRPlayBands::getBandLow(unsigned int band_index)
1159 {
1160  if (band_index < m_nb_bands)
1161  {
1162  return m_bandLow[band_index];
1163  }
1164  else
1165  {
1166  return m_bandLow[0];
1167  }
1168 }
1169 
1170 unsigned int SDRPlayBands::getBandHigh(unsigned int band_index)
1171 {
1172  if (band_index < m_nb_bands)
1173  {
1174  return m_bandHigh[band_index];
1175  }
1176  else
1177  {
1178  return m_bandHigh[0];
1179  }
1180 }
1181 
1182 
1184 {
1185  return SDRPlayBands::m_nb_bands;
1186 }
1187 
QMutex m_mutex
Definition: sdrplayinput.h:185
static unsigned int getNbRates()
virtual bool handleMessage(const Message &message)
uint32_t m_ifFrequencyIndex
bool startDeviceEngine()
Start the device engine corresponding to the stream type.
Definition: deviceapi.cpp:253
void setFileRecordName(QString *file_record_name)
void setSdrPlayReport(SWGSDRPlayReport *sdr_play_report)
void webapiReverseSendSettings(QList< QString > &deviceSettingsKeys, const SDRPlaySettings &settings, bool force)
void setIntermediateFrequencies(QList< SWGFrequency *> *intermediate_frequencies)
void setBandwidths(QList< SWGBandwidth *> *bandwidths)
virtual bool deserialize(const QByteArray &data)
uint16_t m_reverseAPIPort
static qint64 calculateDeviceCenterFrequency(quint64 centerFrequency, qint64 transverterDeltaFrequency, int log2Decim, fcPos_t fcPos, quint32 devSampleRate, FrequencyShiftScheme frequencyShiftScheme, bool transverterMode=false)
void push(Message *message, bool emitSignal=true)
Push message onto queue.
SDRPlayThread * m_sdrPlayThread
Definition: sdrplayinput.h:189
void stopDeviceEngine()
Stop the device engine corresponding to the stream type.
Definition: deviceapi.cpp:266
QList< SWGSampleRate * > * getSampleRates()
void setReverseApiPort(qint32 reverse_api_port)
void setFileName(const QString &filename)
Definition: filerecord.cpp:59
void setIqCorrection(qint32 iq_correction)
uint getDeviceUID() const
Return the current device engine unique ID.
Definition: deviceapi.cpp:303
bool setDeviceCenterFrequency(quint64 freq)
static unsigned int m_rates[m_nb_rates]
Definition: sdrplayinput.h:219
virtual void destroy()
static unsigned int m_bandHigh[m_nb_bands]
Definition: sdrplayinput.h:251
static unsigned int m_if[m_nb_if]
Definition: sdrplayinput.h:239
void setTunerGain(qint32 tuner_gain)
SWGSDRPlaySettings * getSdrPlaySettings()
static MsgStartStop * create(bool startStop)
Definition: sdrplayinput.h:125
virtual int webapiSettingsPutPatch(bool force, const QStringList &deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings &response, QString &errorMessage)
void startRecording()
Definition: filerecord.cpp:105
MessageQueue m_inputMessageQueue
Input queue to the source.
virtual void stop()
virtual QString asJson() override
void setFrequencyBands(QList< SWGFrequencyBand *> *frequency_bands)
MessageQueue * getDeviceEngineInputMessageQueue()
Device engine message queue.
Definition: deviceapi.cpp:316
static unsigned int getNbBands()
static const unsigned int m_nb_bw
Definition: sdrplayinput.h:228
static const unsigned int m_nb_if
Definition: sdrplayinput.h:238
static unsigned int getNbBandwidths()
virtual quint64 getCenterFrequency() const
Center frequency exposed by the source.
static const char * m_bandName[m_nb_bands]
Definition: sdrplayinput.h:252
void setBasebandGain(qint32 baseband_gain)
QString m_deviceDescription
Definition: sdrplayinput.h:190
void setSdrPlaySettings(SWGSDRPlaySettings *sdr_play_settings)
bool initDeviceEngine()
Init the device engine corresponding to the stream type.
Definition: deviceapi.cpp:240
static unsigned int getNbIFs()
void setIfFrequencyIndex(qint32 if_frequency_index)
static unsigned int getRateIndex(unsigned int rate)
virtual QByteArray serialize() const
void setOriginatorIndex(qint32 originator_index)
const SDRPlaySettings & getSettings() const
Definition: sdrplayinput.h:52
virtual void setCenterFrequency(qint64 centerFrequency)
SWGSDRPlayReport * getSdrPlayReport()
SampleSinkFifo m_sampleFifo
bool setSize(int size)
MessageQueue * getMessageQueueToGUI()
static MsgReportSDRPlayGains * create(int lnaGain, int mixerGain, int basebandGain, int tunerGain)
Definition: sdrplayinput.h:75
void setUseReverseApi(qint32 use_reverse_api)
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
virtual bool handleMessage(const Message &message)
Processing of a message. Returns true if message has actually been processed.
Definition: filerecord.cpp:128
void networkManagerFinished(QNetworkReply *reply)
bool applySettings(const SDRPlaySettings &settings, bool forwardChange, bool force)
QNetworkRequest m_networkRequest
Definition: sdrplayinput.h:195
static const unsigned int m_nb_bands
Definition: sdrplayinput.h:249
void setTunerGainMode(qint32 tuner_gain_mode)
void webapiReverseSendStartStop(bool start)
FileRecord * m_fileSink
File sink to record device I/Q output.
Definition: sdrplayinput.h:193
int getDeviceSetIndex() const
Definition: deviceapi.h:131
virtual void init()
initializations to be done when all collaborating objects are created and possibly connected ...
void setReverseApiDeviceIndex(qint32 reverse_api_device_index)
#define MESSAGE_CLASS_DEFINITION(Name, BaseClass)
Definition: message.h:52
QString m_reverseAPIAddress
void genUniqueFileName(uint deviceUID, int istream=-1)
Definition: filerecord.cpp:67
QByteArray serialize() const
static unsigned int m_bw[m_nb_bw]
Definition: sdrplayinput.h:229
static MsgConfigureSDRPlay * create(const SDRPlaySettings &settings, bool force)
Definition: sdrplayinput.h:55
void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport &response)
virtual ~SDRPlayInput()
SDRPlayVariant m_variant
Definition: sdrplayinput.h:186
QString m_fileRecordName
virtual int webapiReportGet(SWGSDRangel::SWGDeviceReport &response, QString &errorMessage)
void setLog2Decimation(unsigned int log2_decim)
void setLog2Decim(qint32 log2_decim)
void setFrequencyBandIndex(qint32 frequency_band_index)
virtual bool start()
void stopRecording()
Definition: filerecord.cpp:117
int32_t i
Definition: decimators.h:244
DeviceAPI * m_deviceAPI
Definition: sdrplayinput.h:184
static bool match(const Message *message)
Definition: message.cpp:45
uint64_t m_centerFrequency
void setCenterFrequency(qint32 center_frequency)
static unsigned int getBandLow(unsigned int band_index)
static unsigned int getBandwidth(unsigned int bandwidth_index)
void removeAncillarySink(BasebandSampleSink *sink, unsigned int index=0)
Removes it.
Definition: deviceapi.cpp:100
virtual const QString & getDeviceDescription() const
QNetworkAccessManager * m_networkManager
Definition: sdrplayinput.h:194
static unsigned int m_bandLow[m_nb_bands]
Definition: sdrplayinput.h:250
uint32_t m_frequencyBandIndex
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings &response, const SDRPlaySettings &settings)
void setBandwidthIndex(qint32 bandwidth_index)
QList< SWGBandwidth * > * getBandwidths()
void getDeviceEngineStateStr(QString &state)
Definition: deviceapi.cpp:389
static const unsigned int m_nb_rates
Definition: sdrplayinput.h:218
uint32_t m_log2Decim
uint32_t m_bandwidthIndex
static unsigned int getBandwidthIndex(unsigned int bandwidth)
bool deserialize(const QByteArray &data)
static unsigned int getIFIndex(unsigned int iff)
QList< SWGFrequency * > * getIntermediateFrequencies()
void setLOppmTenths(qint32 l_oppm_tenths)
QList< SWGFrequencyBand * > * getFrequencyBands()
void setDevSampleRateIndex(qint32 dev_sample_rate_index)
virtual int webapiSettingsGet(SWGSDRangel::SWGDeviceSettings &response, QString &errorMessage)
static unsigned int getRate(unsigned int rate_index)
static unsigned int getIF(unsigned int if_index)
bool openDevice()
static unsigned int getBandHigh(unsigned int band_index)
SDRPlaySettings m_settings
Definition: sdrplayinput.h:187
void setSampleRates(QList< SWGSampleRate *> *sample_rates)
virtual int getSampleRate() const
Sample rate exposed by the source.
static QString getBandName(unsigned int band_index)
void closeDevice()
virtual int webapiRunGet(SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
void configureCorrections(bool dcOffsetCorrection, bool iqImbalanceCorrection, int streamIndex=0)
Configure current device engine DSP corrections (Rx)
Definition: deviceapi.cpp:355
uint16_t m_reverseAPIDeviceIndex
uint32_t m_devSampleRateIndex
void setFcPos(int fcPos)
uint32_t getSamplingDeviceSequence() const
Definition: deviceapi.h:123
void setDirection(qint32 direction)
void setMixerAmpOn(qint32 mixer_amp_on)
void setReverseApiAddress(QString *reverse_api_address)
mirisdr_dev_t * m_dev
Definition: sdrplayinput.h:188
void setDeviceHwType(QString *device_hw_type)
virtual int webapiRun(bool run, SWGSDRangel::SWGDeviceState &response, QString &errorMessage)