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 Slots | Private Member Functions | Private Attributes | List of all members
SoapySDROutput Class Reference

#include <soapysdroutput.h>

+ Inheritance diagram for SoapySDROutput:
+ Collaboration diagram for SoapySDROutput:

Classes

class  MsgConfigureSoapySDROutput
 
class  MsgReportGainChange
 
class  MsgStartStop
 

Public Member Functions

 SoapySDROutput (DeviceAPI *deviceAPI)
 
virtual ~SoapySDROutput ()
 
virtual void destroy ()
 
virtual void init ()
 initializations to be done when all collaborating objects are created and possibly connected More...
 
virtual bool start ()
 
virtual void stop ()
 
SoapySDROutputThreadgetThread ()
 
void setThread (SoapySDROutputThread *thread)
 
virtual QByteArray serialize () const
 
virtual bool deserialize (const QByteArray &data)
 
virtual void setMessageQueueToGUI (MessageQueue *queue)
 
virtual const QString & getDeviceDescription () const
 
virtual int getSampleRate () const
 Sample rate exposed by the sink. More...
 
virtual void setSampleRate (int sampleRate)
 For when the sink sample rate is set externally. More...
 
virtual quint64 getCenterFrequency () const
 Center frequency exposed by the sink. More...
 
virtual void setCenterFrequency (qint64 centerFrequency)
 
virtual bool handleMessage (const Message &message)
 
void getFrequencyRange (uint64_t &min, uint64_t &max)
 
void getGlobalGainRange (int &min, int &max)
 
bool isAGCSupported ()
 
const SoapySDR::RangeList & getRateRanges ()
 
const std::vector< std::string > & getAntennas ()
 
const SoapySDR::RangeList & getBandwidthRanges ()
 
const std::vector< DeviceSoapySDRParams::FrequencySetting > & getTunableElements ()
 
const std::vector< DeviceSoapySDRParams::GainSetting > & getIndividualGainsRanges ()
 
const SoapySDR::ArgInfoList & getStreamArgInfoList ()
 
const SoapySDR::ArgInfoList & getDeviceArgInfoList ()
 
void initGainSettings (SoapySDROutputSettings &settings)
 
void initTunableElementsSettings (SoapySDROutputSettings &settings)
 
void initStreamArgSettings (SoapySDROutputSettings &settings)
 
void initDeviceArgSettings (SoapySDROutputSettings &settings)
 
bool hasDCAutoCorrection ()
 
bool hasDCCorrectionValue ()
 
bool hasIQAutoCorrection ()
 
bool hasIQCorrectionValue ()
 
virtual int webapiSettingsGet (SWGSDRangel::SWGDeviceSettings &response, QString &errorMessage)
 
virtual int webapiSettingsPutPatch (bool force, const QStringList &deviceSettingsKeys, SWGSDRangel::SWGDeviceSettings &response, QString &errorMessage)
 
virtual int webapiReportGet (SWGSDRangel::SWGDeviceReport &response, QString &errorMessage)
 
virtual int webapiRunGet (SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
 
virtual int webapiRun (bool run, SWGSDRangel::SWGDeviceState &response, QString &errorMessage)
 
- Public Member Functions inherited from DeviceSampleSink
 DeviceSampleSink ()
 
virtual ~DeviceSampleSink ()
 
MessageQueuegetInputMessageQueue ()
 
MessageQueuegetMessageQueueToGUI ()
 
SampleSourceFifogetSampleFifo ()
 

Private Slots

void networkManagerFinished (QNetworkReply *reply)
 

Private Member Functions

bool openDevice ()
 
void closeDevice ()
 
SoapySDROutputThreadfindThread ()
 
void moveThreadToBuddy ()
 
bool applySettings (const SoapySDROutputSettings &settings, bool force=false)
 
bool setDeviceCenterFrequency (SoapySDR::Device *dev, int requestedChannel, quint64 freq_hz, int loPpmTenths)
 
void updateGains (SoapySDR::Device *dev, int requestedChannel, SoapySDROutputSettings &settings)
 
void updateTunableElements (SoapySDR::Device *dev, int requestedChannel, SoapySDROutputSettings &settings)
 
void webapiFormatDeviceSettings (SWGSDRangel::SWGDeviceSettings &response, const SoapySDROutputSettings &settings)
 
void webapiFormatDeviceReport (SWGSDRangel::SWGDeviceReport &response)
 
QVariant webapiVariantFromArgValue (SWGSDRangel::SWGArgValue *argValue)
 
void webapiFormatArgValue (const QVariant &v, SWGSDRangel::SWGArgValue *argValue)
 
void webapiFormatArgInfo (const SoapySDR::ArgInfo &arg, SWGSDRangel::SWGArgInfo *argInfo)
 
void webapiReverseSendSettings (QList< QString > &deviceSettingsKeys, const SoapySDROutputSettings &settings, bool force)
 
void webapiReverseSendStartStop (bool start)
 

Private Attributes

DeviceAPIm_deviceAPI
 
QMutex m_mutex
 
SoapySDROutputSettings m_settings
 
QString m_deviceDescription
 
bool m_running
 
SoapySDROutputThreadm_thread
 
DeviceSoapySDRShared m_deviceShared
 
QNetworkAccessManager * m_networkManager
 
QNetworkRequest m_networkRequest
 

Additional Inherited Members

- Public Types inherited from DeviceSampleSink
enum  fcPos_t { FC_POS_INFRA = 0, FC_POS_SUPRA, FC_POS_CENTER }
 
- Static Public Member Functions inherited from DeviceSampleSink
static qint64 calculateDeviceCenterFrequency (quint64 centerFrequency, qint64 transverterDeltaFrequency, int log2Interp, fcPos_t fcPos, quint32 devSampleRate, bool transverterMode=false)
 
static qint64 calculateCenterFrequency (quint64 deviceCenterFrequency, qint64 transverterDeltaFrequency, int log2Interp, fcPos_t fcPos, quint32 devSampleRate, bool transverterMode=false)
 
static qint32 calculateFrequencyShift (int log2Interp, fcPos_t fcPos, quint32 devSampleRate)
 
- Protected Slots inherited from DeviceSampleSink
void handleInputMessages ()
 
- Protected Attributes inherited from DeviceSampleSink
SampleSourceFifo m_sampleSourceFifo
 
MessageQueue m_inputMessageQueue
 Input queue to the sink. More...
 
MessageQueuem_guiMessageQueue
 Input message queue to the GUI. More...
 

Detailed Description

Definition at line 49 of file soapysdroutput.h.

Constructor & Destructor Documentation

◆ SoapySDROutput()

SoapySDROutput::SoapySDROutput ( DeviceAPI deviceAPI)

Definition at line 41 of file soapysdroutput.cpp.

41  :
42  m_deviceAPI(deviceAPI),
43  m_deviceDescription("SoapySDROutput"),
44  m_running(false),
45  m_thread(0)
46 {
48  openDevice();
53 
54  m_networkManager = new QNetworkAccessManager();
55  connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
56 }
void initStreamArgSettings(SoapySDROutputSettings &settings)
void setNbSinkStreams(uint32_t nbSinkStreams)
Definition: deviceapi.h:169
void initDeviceArgSettings(SoapySDROutputSettings &settings)
QString m_deviceDescription
void initGainSettings(SoapySDROutputSettings &settings)
SoapySDROutputSettings m_settings
void networkManagerFinished(QNetworkReply *reply)
void initTunableElementsSettings(SoapySDROutputSettings &settings)
DeviceAPI * m_deviceAPI
QNetworkAccessManager * m_networkManager
SoapySDROutputThread * m_thread

◆ ~SoapySDROutput()

SoapySDROutput::~SoapySDROutput ( )
virtual

Definition at line 58 of file soapysdroutput.cpp.

References closeDevice(), m_networkManager, m_running, networkManagerFinished(), and stop().

59 {
60  disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
61  delete m_networkManager;
62 
63  if (m_running) {
64  stop();
65  }
66 
67  closeDevice();
68 }
void networkManagerFinished(QNetworkReply *reply)
virtual void stop()
QNetworkAccessManager * m_networkManager
+ Here is the call graph for this function:

Member Function Documentation

◆ applySettings()

bool SoapySDROutput::applySettings ( const SoapySDROutputSettings settings,
bool  force = false 
)
private

Definition at line 854 of file soapysdroutput.cpp.

References DeviceSoapySDRShared::MsgReportBuddyChange::create(), SoapySDROutput::MsgReportGainChange::create(), DeviceSoapySDRShared::MsgReportDeviceArgsChange::create(), findThread(), DeviceAPI::getDeviceEngineInputMessageQueue(), DeviceAPI::getDeviceItemIndex(), SoapySDROutputThread::getFifo(), DeviceSampleSink::getMessageQueueToGUI(), DeviceAPI::getSinkBuddies(), DeviceAPI::getSourceBuddies(), hasDCAutoCorrection(), hasDCCorrectionValue(), hasIQCorrectionValue(), SoapySDROutputThread::isRunning(), SoapySDROutputSettings::m_antenna, SoapySDROutputSettings::m_autoDCCorrection, SoapySDROutputSettings::m_autoGain, SoapySDROutputSettings::m_bandwidth, SoapySDROutputSettings::m_centerFrequency, SoapySDROutputSettings::m_dcCorrection, DeviceSoapySDRShared::m_device, m_deviceAPI, SoapySDROutputSettings::m_deviceArgSettings, m_deviceShared, SoapySDROutputSettings::m_devSampleRate, SoapySDROutputSettings::m_globalGain, SoapySDROutputSettings::m_individualGains, SoapySDROutputSettings::m_iqCorrection, SoapySDROutputSettings::m_log2Interp, SoapySDROutputSettings::m_LOppmTenths, SoapySDROutputSettings::m_reverseAPIAddress, SoapySDROutputSettings::m_reverseAPIDeviceIndex, SoapySDROutputSettings::m_reverseAPIPort, DeviceSoapySDRShared::m_sampleFifoLengthInSeconds, DeviceSoapySDRShared::m_sampleFifoMinSize, DeviceSoapySDRShared::m_sampleFifoMinSize32, DeviceSampleSink::m_sampleSourceFifo, m_settings, SoapySDROutputSettings::m_streamArgSettings, SoapySDROutputSettings::m_transverterDeltaFrequency, SoapySDROutputSettings::m_transverterMode, SoapySDROutputSettings::m_tunableElements, SoapySDROutputSettings::m_useReverseAPI, leansdr::max(), MessageQueue::push(), SampleSourceFifo::resize(), setDeviceCenterFrequency(), SoapySDROutputThread::setFifo(), SoapySDROutputThread::setLog2Interpolation(), SoapySDROutputThread::setSampleRate(), SoapySDROutputThread::startWork(), SoapySDROutputThread::stopWork(), updateGains(), and webapiReverseSendSettings().

Referenced by handleMessage(), init(), and stop().

855 {
856  bool forwardChangeOwnDSP = false;
857  bool forwardChangeToBuddies = false;
858  bool globalGainChanged = false;
859  bool individualGainsChanged = false;
860  bool deviceArgsChanged = false;
861  QList<QString> reverseAPIKeys;
862 
863  SoapySDR::Device *dev = m_deviceShared.m_device;
864  SoapySDROutputThread *outputThread = findThread();
865  int requestedChannel = m_deviceAPI->getDeviceItemIndex();
866  qint64 xlatedDeviceCenterFrequency = settings.m_centerFrequency;
867  xlatedDeviceCenterFrequency -= settings.m_transverterMode ? settings.m_transverterDeltaFrequency : 0;
868  xlatedDeviceCenterFrequency = xlatedDeviceCenterFrequency < 0 ? 0 : xlatedDeviceCenterFrequency;
869 
870  // resize FIFO
871  if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || (m_settings.m_log2Interp != settings.m_log2Interp) || force)
872  {
873  SoapySDROutputThread *soapySDROutputThread = findThread();
874  SampleSourceFifo *fifo = 0;
875 
876  if (soapySDROutputThread)
877  {
878  fifo = soapySDROutputThread->getFifo(requestedChannel);
879  soapySDROutputThread->setFifo(requestedChannel, 0);
880  }
881 
882  int fifoSize;
883 
884  if (settings.m_log2Interp >= 5)
885  {
887  }
888  else
889  {
890  fifoSize = std::max(
893  }
894 
895  m_sampleSourceFifo.resize(fifoSize);
896 
897  if (fifo) {
898  soapySDROutputThread->setFifo(requestedChannel, &m_sampleSourceFifo);
899  }
900  }
901 
902  if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || force)
903  {
904  reverseAPIKeys.append("devSampleRate");
905  forwardChangeOwnDSP = true;
906  forwardChangeToBuddies = true;
907 
908  if (dev != 0)
909  {
910  try
911  {
912  dev->setSampleRate(SOAPY_SDR_TX, requestedChannel, settings.m_devSampleRate);
913  qDebug() << "SoapySDROutput::applySettings: setSampleRate OK: " << settings.m_devSampleRate;
914 
915  if (outputThread)
916  {
917  bool wasRunning = outputThread->isRunning();
918  outputThread->stopWork();
919  outputThread->setSampleRate(settings.m_devSampleRate);
920 
921  if (wasRunning) {
922  outputThread->startWork();
923  }
924  }
925  }
926  catch (const std::exception &ex)
927  {
928  qCritical("SoapySDROutput::applySettings: could not set sample rate: %d: %s",
929  settings.m_devSampleRate, ex.what());
930  }
931  }
932  }
933 
934  if ((m_settings.m_log2Interp != settings.m_log2Interp) || force)
935  {
936  reverseAPIKeys.append("log2Interp");
937  forwardChangeOwnDSP = true;
938 
939  if (outputThread != 0)
940  {
941  outputThread->setLog2Interpolation(requestedChannel, settings.m_log2Interp);
942  qDebug() << "SoapySDROutput::applySettings: set decimation to " << (1<<settings.m_log2Interp);
943  }
944  }
945 
946  if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) {
947  reverseAPIKeys.append("centerFrequency");
948  }
949  if ((m_settings.m_transverterMode != settings.m_transverterMode) || force) {
950  reverseAPIKeys.append("transverterMode");
951  }
953  reverseAPIKeys.append("transverterDeltaFrequency");
954  }
955  if ((m_settings.m_LOppmTenths != settings.m_LOppmTenths) || force) {
956  reverseAPIKeys.append("LOppmTenths");
957  }
958 
962  || (m_settings.m_LOppmTenths != settings.m_LOppmTenths)
964  || (m_settings.m_log2Interp != settings.m_log2Interp) || force)
965  {
966  forwardChangeOwnDSP = true;
967  forwardChangeToBuddies = true;
968 
969  if (dev != 0) {
970  setDeviceCenterFrequency(dev, requestedChannel, settings.m_centerFrequency, settings.m_LOppmTenths);
971  }
972  }
973 
974  if ((m_settings.m_antenna != settings.m_antenna) || force)
975  {
976  reverseAPIKeys.append("antenna");
977 
978  if (dev != 0)
979  {
980  try
981  {
982  dev->setAntenna(SOAPY_SDR_TX, requestedChannel, settings.m_antenna.toStdString());
983  qDebug("SoapySDROutput::applySettings: set antenna to %s", settings.m_antenna.toStdString().c_str());
984  }
985  catch (const std::exception &ex)
986  {
987  qCritical("SoapySDROutput::applySettings: cannot set antenna to %s: %s",
988  settings.m_antenna.toStdString().c_str(), ex.what());
989  }
990  }
991  }
992 
993  if ((m_settings.m_bandwidth != settings.m_bandwidth) || force)
994  {
995  reverseAPIKeys.append("bandwidth");
996  forwardChangeToBuddies = true;
997 
998  if (dev != 0)
999  {
1000  try
1001  {
1002  dev->setBandwidth(SOAPY_SDR_TX, requestedChannel, settings.m_bandwidth);
1003  qDebug("SoapySDROutput::applySettings: bandwidth set to %u", settings.m_bandwidth);
1004  }
1005  catch (const std::exception &ex)
1006  {
1007  qCritical("SoapySDROutput::applySettings: cannot set bandwidth to %u: %s",
1008  settings.m_bandwidth, ex.what());
1009  }
1010  }
1011  }
1012 
1013  for (const auto &oname : m_settings.m_tunableElements.keys())
1014  {
1015  auto nvalue = settings.m_tunableElements.find(oname);
1016 
1017  if (nvalue != settings.m_tunableElements.end() && ((m_settings.m_tunableElements[oname] != *nvalue) || force))
1018  {
1019  if (dev != 0)
1020  {
1021  try
1022  {
1023  dev->setFrequency(SOAPY_SDR_TX, requestedChannel, oname.toStdString(), *nvalue);
1024  qDebug("SoapySDROutput::applySettings: tunable element %s frequency set to %lf",
1025  oname.toStdString().c_str(), *nvalue);
1026  }
1027  catch (const std::exception &ex)
1028  {
1029  qCritical("SoapySDROutput::applySettings: cannot set tunable element %s to %lf: %s",
1030  oname.toStdString().c_str(), *nvalue, ex.what());
1031  }
1032  }
1033 
1034  m_settings.m_tunableElements[oname] = *nvalue;
1035  }
1036  }
1037 
1038  if ((m_settings.m_globalGain != settings.m_globalGain) || force)
1039  {
1040  reverseAPIKeys.append("globalGain");
1041 
1042  if (dev != 0)
1043  {
1044  try
1045  {
1046  dev->setGain(SOAPY_SDR_TX, requestedChannel, settings.m_globalGain);
1047  qDebug("SoapySDROutput::applySettings: set global gain to %d", settings.m_globalGain);
1048  globalGainChanged = true;
1049  }
1050  catch (const std::exception &ex)
1051  {
1052  qCritical("SoapySDROutput::applySettings: cannot set global gain to %d: %s",
1053  settings.m_globalGain, ex.what());
1054  }
1055  }
1056  }
1057 
1058  for (const auto &oname : m_settings.m_individualGains.keys())
1059  {
1060  auto nvalue = settings.m_individualGains.find(oname);
1061 
1062  if (nvalue != settings.m_individualGains.end() && ((m_settings.m_individualGains[oname] != *nvalue) || force))
1063  {
1064  if (dev != 0)
1065  {
1066  try
1067  {
1068  dev->setGain(SOAPY_SDR_TX, requestedChannel, oname.toStdString(), *nvalue);
1069  qDebug("SoapySDROutput::applySettings: individual gain %s set to %lf",
1070  oname.toStdString().c_str(), *nvalue);
1071  individualGainsChanged = true;
1072  }
1073  catch (const std::exception &ex)
1074  {
1075  qCritical("SoapySDROutput::applySettings: cannot set individual gain %s to %lf: %s",
1076  oname.toStdString().c_str(), *nvalue, ex.what());
1077  }
1078  }
1079 
1080  m_settings.m_individualGains[oname] = *nvalue;
1081  }
1082  }
1083 
1084  if ((m_settings.m_autoGain != settings.m_autoGain) || force)
1085  {
1086  reverseAPIKeys.append("autoGain");
1087 
1088  if (dev != 0)
1089  {
1090  try
1091  {
1092  dev->setGainMode(SOAPY_SDR_TX, requestedChannel, settings.m_autoGain);
1093  qDebug("SoapySDROutput::applySettings: %s AGC", settings.m_autoGain ? "set" : "unset");
1094  }
1095  catch (const std::exception &ex)
1096  {
1097  qCritical("SoapySDROutput::applySettings: cannot %s AGC", settings.m_autoGain ? "set" : "unset");
1098  }
1099  }
1100  }
1101 
1102  if ((m_settings.m_autoDCCorrection != settings.m_autoDCCorrection) || force)
1103  {
1104  reverseAPIKeys.append("autoDCCorrection");
1105 
1106  if ((dev != 0) && hasDCAutoCorrection())
1107  {
1108  try
1109  {
1110  dev->setDCOffsetMode(SOAPY_SDR_TX, requestedChannel, settings.m_autoDCCorrection);
1111  qDebug("SoapySDROutput::applySettings: %s DC auto correction", settings.m_autoDCCorrection ? "set" : "unset");
1112  }
1113  catch (const std::exception &ex)
1114  {
1115  qCritical("SoapySDROutput::applySettings: cannot %s DC auto correction", settings.m_autoDCCorrection ? "set" : "unset");
1116  }
1117  }
1118  }
1119 
1120  if ((m_settings.m_dcCorrection != settings.m_dcCorrection) || force)
1121  {
1122  reverseAPIKeys.append("dcCorrection");
1123 
1124  if ((dev != 0) && hasDCCorrectionValue())
1125  {
1126  try
1127  {
1128  dev->setDCOffset(SOAPY_SDR_TX, requestedChannel, settings.m_dcCorrection);
1129  qDebug("SoapySDROutput::applySettings: DC offset correction set to (%lf, %lf)", settings.m_dcCorrection.real(), settings.m_dcCorrection.imag());
1130  }
1131  catch (const std::exception &ex)
1132  {
1133  qCritical("SoapySDROutput::applySettings: cannot set DC offset correction to (%lf, %lf)", settings.m_dcCorrection.real(), settings.m_dcCorrection.imag());
1134  }
1135  }
1136  }
1137 
1138  if ((m_settings.m_iqCorrection != settings.m_iqCorrection) || force)
1139  {
1140  reverseAPIKeys.append("iqCorrection");
1141 
1142  if ((dev != 0) && hasIQCorrectionValue())
1143  {
1144  try
1145  {
1146  dev->setIQBalance(SOAPY_SDR_TX, requestedChannel, settings.m_iqCorrection);
1147  qDebug("SoapySDROutput::applySettings: IQ balance correction set to (%lf, %lf)", settings.m_iqCorrection.real(), settings.m_iqCorrection.imag());
1148  }
1149  catch (const std::exception &ex)
1150  {
1151  qCritical("SoapySDROutput::applySettings: cannot set IQ balance correction to (%lf, %lf)", settings.m_iqCorrection.real(), settings.m_iqCorrection.imag());
1152  }
1153  }
1154  }
1155 
1156  for (const auto &oname : m_settings.m_streamArgSettings.keys())
1157  {
1158  auto nvalue = settings.m_streamArgSettings.find(oname);
1159 
1160  if (nvalue != settings.m_streamArgSettings.end() && ((m_settings.m_streamArgSettings[oname] != *nvalue) || force))
1161  {
1162  if (dev != 0)
1163  {
1164  try
1165  {
1166  dev->writeSetting(SOAPY_SDR_TX, requestedChannel, oname.toStdString(), nvalue->toString().toStdString());
1167  qDebug("SoapySDROutput::applySettings: stream argument %s set to %s",
1168  oname.toStdString().c_str(), nvalue->toString().toStdString().c_str());
1169  }
1170  catch (const std::exception &ex)
1171  {
1172  qCritical("SoapySDROutput::applySettings: cannot set stream argument %s to %s: %s",
1173  oname.toStdString().c_str(), nvalue->toString().toStdString().c_str(), ex.what());
1174  }
1175  }
1176 
1177  m_settings.m_streamArgSettings[oname] = *nvalue;
1178  }
1179  }
1180 
1181  for (const auto &oname : m_settings.m_deviceArgSettings.keys())
1182  {
1183  auto nvalue = settings.m_deviceArgSettings.find(oname);
1184 
1185  if (nvalue != settings.m_deviceArgSettings.end() && ((m_settings.m_deviceArgSettings[oname] != *nvalue) || force))
1186  {
1187  if (dev != 0)
1188  {
1189  try
1190  {
1191  dev->writeSetting(oname.toStdString(), nvalue->toString().toStdString());
1192  qDebug("SoapySDROutput::applySettings: device argument %s set to %s",
1193  oname.toStdString().c_str(), nvalue->toString().toStdString().c_str());
1194  }
1195  catch (const std::exception &ex)
1196  {
1197  qCritical("SoapySDRInput::applySettings: cannot set device argument %s to %s: %s",
1198  oname.toStdString().c_str(), nvalue->toString().toStdString().c_str(), ex.what());
1199  }
1200  }
1201 
1202  m_settings.m_deviceArgSettings[oname] = *nvalue;
1203  deviceArgsChanged = true;
1204  }
1205  }
1206 
1207  if (forwardChangeOwnDSP)
1208  {
1209  int sampleRate = settings.m_devSampleRate/(1<<settings.m_log2Interp);
1210  DSPSignalNotification *notif = new DSPSignalNotification(sampleRate, settings.m_centerFrequency);
1212  }
1213 
1214  if (forwardChangeToBuddies)
1215  {
1216  // send to buddies
1217  const std::vector<DeviceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies();
1218  const std::vector<DeviceAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
1219 
1220  for (const auto &itSource : sourceBuddies)
1221  {
1223  settings.m_centerFrequency,
1224  settings.m_LOppmTenths,
1225  2,
1226  settings.m_devSampleRate,
1227  false);
1228  itSource->getSamplingDeviceInputMessageQueue()->push(report);
1229  }
1230 
1231  for (const auto &itSink : sinkBuddies)
1232  {
1234  settings.m_centerFrequency,
1235  settings.m_LOppmTenths,
1236  2,
1237  settings.m_devSampleRate,
1238  false);
1239  itSink->getSamplingDeviceInputMessageQueue()->push(report);
1240  }
1241  }
1242 
1243  if (deviceArgsChanged)
1244  {
1245  // send to buddies
1246  const std::vector<DeviceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies();
1247  const std::vector<DeviceAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
1248 
1249  for (const auto &itSource : sourceBuddies)
1250  {
1252  settings.m_deviceArgSettings);
1253  itSource->getSamplingDeviceInputMessageQueue()->push(report);
1254  }
1255 
1256  for (const auto &itSink : sinkBuddies)
1257  {
1259  settings.m_deviceArgSettings);
1260  itSink->getSamplingDeviceInputMessageQueue()->push(report);
1261  }
1262  }
1263 
1264  if (settings.m_useReverseAPI)
1265  {
1266  bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) ||
1270 
1271  if (fullUpdate || force) {
1272  webapiReverseSendSettings(reverseAPIKeys, settings, true);
1273  } else if (reverseAPIKeys.size() != 0) {
1274  webapiReverseSendSettings(reverseAPIKeys, settings, false);
1275  }
1276  }
1277 
1278  m_settings = settings;
1279 
1280  if (globalGainChanged || individualGainsChanged)
1281  {
1282  if (dev) {
1283  updateGains(dev, requestedChannel, m_settings);
1284  }
1285 
1286  if (getMessageQueueToGUI())
1287  {
1288  MsgReportGainChange *report = MsgReportGainChange::create(m_settings, globalGainChanged, individualGainsChanged);
1289  getMessageQueueToGUI()->push(report);
1290  }
1291  }
1292 
1293  qDebug() << "SoapySDROutput::applySettings: "
1294  << " m_transverterMode: " << m_settings.m_transverterMode
1295  << " m_transverterDeltaFrequency: " << m_settings.m_transverterDeltaFrequency
1296  << " m_centerFrequency: " << m_settings.m_centerFrequency << " Hz"
1297  << " m_LOppmTenths: " << m_settings.m_LOppmTenths
1298  << " m_log2Interp: " << m_settings.m_log2Interp
1299  << " m_devSampleRate: " << m_settings.m_devSampleRate
1300  << " m_bandwidth: " << m_settings.m_bandwidth
1301  << " m_globalGain: " << m_settings.m_globalGain
1302  << " force: " << force;
1303 
1304  QMap<QString, double>::const_iterator doubleIt = m_settings.m_individualGains.begin();
1305 
1306  for(; doubleIt != m_settings.m_individualGains.end(); ++doubleIt) {
1307  qDebug("SoapySDROutput::applySettings: m_individualGains[%s]: %lf", doubleIt.key().toStdString().c_str(), doubleIt.value());
1308  }
1309 
1310  doubleIt = m_settings.m_tunableElements.begin();
1311 
1312  for(; doubleIt != m_settings.m_tunableElements.end(); ++doubleIt) {
1313  qDebug("SoapySDROutput::applySettings: m_tunableElements[%s]: %lf", doubleIt.key().toStdString().c_str(), doubleIt.value());
1314  }
1315 
1316  QMap<QString, QVariant>::const_iterator varIt = m_settings.m_deviceArgSettings.begin();
1317 
1318  for(; varIt != m_settings.m_deviceArgSettings.end(); ++varIt)
1319  {
1320  qDebug("SoapySDROutput::applySettings: m_deviceArgSettings[%s] (type %d): %s",
1321  varIt.key().toStdString().c_str(),
1322  (int) varIt.value().type(), // bool: 1, int: 2, double: 6, string: 10 (http://doc.qt.io/archives/qt-4.8/qvariant.html)
1323  varIt.value().toString().toStdString().c_str());
1324  }
1325 
1326  varIt = m_settings.m_streamArgSettings.begin();
1327 
1328  for(; varIt != m_settings.m_streamArgSettings.end(); ++varIt)
1329  {
1330  qDebug("SoapySDROutput::applySettings: m_streamArgSettings[%s] (type %d): %s",
1331  varIt.key().toStdString().c_str(),
1332  (int) varIt.value().type(),
1333  varIt.value().toString().toStdString().c_str());
1334  }
1335 
1336  return true;
1337 }
static const int m_sampleFifoMinSize32
static const int m_sampleFifoMinSize
QMap< QString, double > m_tunableElements
void push(Message *message, bool emitSignal=true)
Push message onto queue.
const std::vector< DeviceAPI * > & getSinkBuddies() const
Definition: deviceapi.h:166
static MsgReportDeviceArgsChange * create(const QMap< QString, QVariant > &deviceArgSettings)
MessageQueue * getDeviceEngineInputMessageQueue()
Device engine message queue.
Definition: deviceapi.cpp:316
bool hasIQCorrectionValue()
uint32_t getDeviceItemIndex() const
Definition: deviceapi.h:129
static MsgReportBuddyChange * create(uint64_t centerFrequency, int LOppmTenths, int fcPos, int devSampleRate, bool rxElseTx)
void updateGains(SoapySDR::Device *dev, int requestedChannel, SoapySDROutputSettings &settings)
void setSampleRate(unsigned int sampleRate)
bool hasDCAutoCorrection()
QMap< QString, QVariant > m_streamArgSettings
QMap< QString, double > m_individualGains
void webapiReverseSendSettings(QList< QString > &deviceSettingsKeys, const SoapySDROutputSettings &settings, bool force)
SoapySDR::Device * m_device
std::complex< double > m_iqCorrection
static const float m_sampleFifoLengthInSeconds
SoapySDROutputSettings m_settings
void setFifo(unsigned int channel, SampleSourceFifo *sampleFifo)
void resize(uint32_t size)
SoapySDROutputThread * findThread()
std::complex< double > m_dcCorrection
SampleSourceFifo m_sampleSourceFifo
const std::vector< DeviceAPI * > & getSourceBuddies() const
Definition: deviceapi.h:165
DeviceSoapySDRShared m_deviceShared
DeviceAPI * m_deviceAPI
SampleSourceFifo * getFifo(unsigned int channel)
MessageQueue * getMessageQueueToGUI()
bool hasDCCorrectionValue()
void setLog2Interpolation(unsigned int channel, unsigned int log2_interp)
QMap< QString, QVariant > m_deviceArgSettings
static MsgReportGainChange * create(const SoapySDROutputSettings &settings, bool globalGain, bool individualGains)
bool setDeviceCenterFrequency(SoapySDR::Device *dev, int requestedChannel, quint64 freq_hz, int loPpmTenths)
T max(const T &x, const T &y)
Definition: framework.h:446
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ closeDevice()

void SoapySDROutput::closeDevice ( )
private

Definition at line 151 of file soapysdroutput.cpp.

References DeviceSoapySDR::closeSoapySdr(), DeviceAPI::getSinkBuddies(), DeviceAPI::getSourceBuddies(), DeviceSoapySDR::instance(), DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_device, m_deviceAPI, m_deviceShared, m_running, DeviceSoapySDRShared::m_sink, m_thread, moveThreadToBuddy(), and stop().

Referenced by ~SoapySDROutput().

152 {
153  if (m_deviceShared.m_device == 0) { // was never open
154  return;
155  }
156 
157  if (m_running) {
158  stop();
159  }
160 
161  if (m_thread) { // stills own the thread => transfer to a buddy
163  }
164 
165  m_deviceShared.m_channel = -1; // publicly release channel
167 
168  // No buddies so effectively close the device
169 
170  if ((m_deviceAPI->getSinkBuddies().size() == 0) && (m_deviceAPI->getSourceBuddies().size() == 0))
171  {
172  DeviceSoapySDR& deviceSoapySDR = DeviceSoapySDR::instance();
173  deviceSoapySDR.closeSoapySdr(m_deviceShared.m_device);
175  }
176 }
int m_channel
allocated channel (-1 if none)
const std::vector< DeviceAPI * > & getSinkBuddies() const
Definition: deviceapi.h:166
static DeviceSoapySDR & instance()
void closeSoapySdr(SoapySDR::Device *device)
SoapySDR::Device * m_device
virtual void stop()
const std::vector< DeviceAPI * > & getSourceBuddies() const
Definition: deviceapi.h:165
DeviceSoapySDRShared m_deviceShared
DeviceAPI * m_deviceAPI
SoapySDROutputThread * m_thread
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ deserialize()

bool SoapySDROutput::deserialize ( const QByteArray &  data)
virtual

Implements DeviceSampleSink.

Definition at line 644 of file soapysdroutput.cpp.

References SoapySDROutput::MsgConfigureSoapySDROutput::create(), SoapySDROutputSettings::deserialize(), DeviceSampleSink::m_guiMessageQueue, DeviceSampleSink::m_inputMessageQueue, m_settings, MessageQueue::push(), and SoapySDROutputSettings::resetToDefaults().

645 {
646  bool success = true;
647 
648  if (!m_settings.deserialize(data))
649  {
651  success = false;
652  }
653 
654  MsgConfigureSoapySDROutput* message = MsgConfigureSoapySDROutput::create(m_settings, true);
655  m_inputMessageQueue.push(message);
656 
657  if (m_guiMessageQueue)
658  {
659  MsgConfigureSoapySDROutput* messageToGUI = MsgConfigureSoapySDROutput::create(m_settings, true);
660  m_guiMessageQueue->push(messageToGUI);
661  }
662 
663  return success;
664 }
static MsgConfigureSoapySDROutput * create(const SoapySDROutputSettings &settings, bool force)
void push(Message *message, bool emitSignal=true)
Push message onto queue.
MessageQueue m_inputMessageQueue
Input queue to the sink.
SoapySDROutputSettings m_settings
bool deserialize(const QByteArray &data)
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
+ Here is the call graph for this function:

◆ destroy()

void SoapySDROutput::destroy ( )
virtual

Implements DeviceSampleSink.

Definition at line 70 of file soapysdroutput.cpp.

71 {
72  delete this;
73 }

◆ findThread()

SoapySDROutputThread * SoapySDROutput::findThread ( )
private

Definition at line 362 of file soapysdroutput.cpp.

References DeviceAPI::getSinkBuddies(), getThread(), m_deviceAPI, and m_thread.

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

363 {
364  if (m_thread == 0) // this does not own the thread
365  {
366  SoapySDROutputThread *soapySDROutputThread = 0;
367 
368  // find a buddy that has allocated the thread
369  const std::vector<DeviceAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
370  std::vector<DeviceAPI*>::const_iterator it = sinkBuddies.begin();
371 
372  for (; it != sinkBuddies.end(); ++it)
373  {
374  SoapySDROutput *buddySink = ((DeviceSoapySDRShared*) (*it)->getBuddySharedPtr())->m_sink;
375 
376  if (buddySink)
377  {
378  soapySDROutputThread = buddySink->getThread();
379 
380  if (soapySDROutputThread) {
381  break;
382  }
383  }
384  }
385 
386  return soapySDROutputThread;
387  }
388  else
389  {
390  return m_thread; // own thread
391  }
392 }
const std::vector< DeviceAPI * > & getSinkBuddies() const
Definition: deviceapi.h:166
SoapySDROutputThread * getThread()
DeviceAPI * m_deviceAPI
SoapySDROutputThread * m_thread
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getAntennas()

const std::vector< std::string > & SoapySDROutput::getAntennas ( )

Definition at line 234 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getTxChannelSettings(), DeviceSoapySDRParams::ChannelSettings::m_antennas, DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_deviceParams, and m_deviceShared.

Referenced by SoapySDROutputGui::SoapySDROutputGui().

235 {
237  return channelSettings->m_antennas;
238 }
int m_channel
allocated channel (-1 if none)
std::vector< std::string > m_antennas
Antenna ports names.
DeviceSoapySDRParams * m_deviceParams
const ChannelSettings * getTxChannelSettings(uint32_t index)
DeviceSoapySDRShared m_deviceShared
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getBandwidthRanges()

const SoapySDR::RangeList & SoapySDROutput::getBandwidthRanges ( )

Definition at line 240 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getTxChannelSettings(), DeviceSoapySDRParams::ChannelSettings::m_bandwidthsRanges, DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_deviceParams, and m_deviceShared.

Referenced by SoapySDROutputGui::SoapySDROutputGui().

241 {
243  return channelSettings->m_bandwidthsRanges;
244 }
int m_channel
allocated channel (-1 if none)
DeviceSoapySDRParams * m_deviceParams
SoapySDR::RangeList m_bandwidthsRanges
list of ranges of bandwidths
const ChannelSettings * getTxChannelSettings(uint32_t index)
DeviceSoapySDRShared m_deviceShared
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getCenterFrequency()

quint64 SoapySDROutput::getCenterFrequency ( ) const
virtual

Center frequency exposed by the sink.

Implements DeviceSampleSink.

Definition at line 677 of file soapysdroutput.cpp.

References SoapySDROutputSettings::m_centerFrequency, and m_settings.

678 {
680 }
SoapySDROutputSettings m_settings

◆ getDeviceArgInfoList()

const SoapySDR::ArgInfoList & SoapySDROutput::getDeviceArgInfoList ( )

Definition at line 258 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getDeviceArgs(), DeviceSoapySDRShared::m_deviceParams, and m_deviceShared.

Referenced by SoapySDROutputGui::SoapySDROutputGui().

259 {
261 }
DeviceSoapySDRParams * m_deviceParams
const SoapySDR::ArgInfoList & getDeviceArgs() const
DeviceSoapySDRShared m_deviceShared
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getDeviceDescription()

const QString & SoapySDROutput::getDeviceDescription ( ) const
virtual

Implements DeviceSampleSink.

Definition at line 666 of file soapysdroutput.cpp.

References m_deviceDescription.

667 {
668  return m_deviceDescription;
669 }
QString m_deviceDescription

◆ getFrequencyRange()

void SoapySDROutput::getFrequencyRange ( uint64_t min,
uint64_t max 
)

Definition at line 178 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getTxChannelSettings(), DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_deviceParams, m_deviceShared, DeviceSoapySDRParams::ChannelSettings::m_frequencySettings, and DeviceSoapySDRParams::FrequencySetting::m_ranges.

Referenced by SoapySDROutputGui::SoapySDROutputGui(), and SoapySDROutputGui::updateFrequencyLimits().

179 {
181 
182  if (channelSettings && (channelSettings->m_frequencySettings.size() > 0))
183  {
184  DeviceSoapySDRParams::FrequencySetting freqSettings = channelSettings->m_frequencySettings[0];
185  SoapySDR::RangeList rangeList = freqSettings.m_ranges;
186 
187  if (rangeList.size() > 0)
188  {
189  SoapySDR::Range range = rangeList[0];
190  min = range.minimum();
191  max = range.maximum();
192  }
193  else
194  {
195  min = 0;
196  max = 0;
197  }
198  }
199  else
200  {
201  min = 0;
202  max = 0;
203  }
204 }
int m_channel
allocated channel (-1 if none)
std::vector< FrequencySetting > m_frequencySettings
tunable elements settings
SoapySDR::RangeList m_ranges
List of ranges of the tunable element.
DeviceSoapySDRParams * m_deviceParams
const ChannelSettings * getTxChannelSettings(uint32_t index)
DeviceSoapySDRShared m_deviceShared
T max(const T &x, const T &y)
Definition: framework.h:446
T min(const T &x, const T &y)
Definition: framework.h:440
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getGlobalGainRange()

void SoapySDROutput::getGlobalGainRange ( int &  min,
int &  max 
)

Definition at line 206 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getTxChannelSettings(), DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_deviceParams, m_deviceShared, and DeviceSoapySDRParams::ChannelSettings::m_gainRange.

Referenced by SoapySDROutputGui::createGlobalGainControl().

207 {
209 
210  if (channelSettings)
211  {
212  min = channelSettings->m_gainRange.minimum();
213  max = channelSettings->m_gainRange.maximum();
214  }
215  else
216  {
217  min = 0;
218  max = 0;
219  }
220 }
int m_channel
allocated channel (-1 if none)
DeviceSoapySDRParams * m_deviceParams
const ChannelSettings * getTxChannelSettings(uint32_t index)
DeviceSoapySDRShared m_deviceShared
T max(const T &x, const T &y)
Definition: framework.h:446
SoapySDR::Range m_gainRange
Global gain range.
T min(const T &x, const T &y)
Definition: framework.h:440
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getIndividualGainsRanges()

const std::vector< DeviceSoapySDRParams::GainSetting > & SoapySDROutput::getIndividualGainsRanges ( )

Definition at line 252 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getTxChannelSettings(), DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_deviceParams, m_deviceShared, and DeviceSoapySDRParams::ChannelSettings::m_gainSettings.

Referenced by SoapySDROutputGui::SoapySDROutputGui().

253 {
255  return channelSettings->m_gainSettings;
256 }
int m_channel
allocated channel (-1 if none)
DeviceSoapySDRParams * m_deviceParams
const ChannelSettings * getTxChannelSettings(uint32_t index)
std::vector< GainSetting > m_gainSettings
gain elements settings
DeviceSoapySDRShared m_deviceShared
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getRateRanges()

const SoapySDR::RangeList & SoapySDROutput::getRateRanges ( )

Definition at line 228 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getTxChannelSettings(), DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_deviceParams, m_deviceShared, and DeviceSoapySDRParams::ChannelSettings::m_ratesRanges.

Referenced by SoapySDROutputGui::SoapySDROutputGui().

229 {
231  return channelSettings->m_ratesRanges;
232 }
int m_channel
allocated channel (-1 if none)
DeviceSoapySDRParams * m_deviceParams
SoapySDR::RangeList m_ratesRanges
list of ranges of sample rates
const ChannelSettings * getTxChannelSettings(uint32_t index)
DeviceSoapySDRShared m_deviceShared
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getSampleRate()

int SoapySDROutput::getSampleRate ( ) const
virtual

Sample rate exposed by the sink.

Implements DeviceSampleSink.

Definition at line 671 of file soapysdroutput.cpp.

References SoapySDROutputSettings::m_devSampleRate, SoapySDROutputSettings::m_log2Interp, and m_settings.

672 {
673  int rate = m_settings.m_devSampleRate;
674  return (rate / (1<<m_settings.m_log2Interp));
675 }
SoapySDROutputSettings m_settings

◆ getStreamArgInfoList()

const SoapySDR::ArgInfoList & SoapySDROutput::getStreamArgInfoList ( )

Definition at line 296 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getTxChannelSettings(), DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_deviceParams, m_deviceShared, and DeviceSoapySDRParams::ChannelSettings::m_streamSettingsArgs.

Referenced by SoapySDROutputGui::SoapySDROutputGui().

297 {
299  return channelSettings->m_streamSettingsArgs;
300 }
int m_channel
allocated channel (-1 if none)
DeviceSoapySDRParams * m_deviceParams
const ChannelSettings * getTxChannelSettings(uint32_t index)
DeviceSoapySDRShared m_deviceShared
SoapySDR::ArgInfoList m_streamSettingsArgs
common stream parameters
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getThread()

SoapySDROutputThread* SoapySDROutput::getThread ( )
inline

Definition at line 127 of file soapysdroutput.h.

Referenced by findThread().

127 { return m_thread; }
SoapySDROutputThread * m_thread
+ Here is the caller graph for this function:

◆ getTunableElements()

const std::vector< DeviceSoapySDRParams::FrequencySetting > & SoapySDROutput::getTunableElements ( )

Definition at line 246 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getTxChannelSettings(), DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_deviceParams, m_deviceShared, and DeviceSoapySDRParams::ChannelSettings::m_frequencySettings.

Referenced by SoapySDROutputGui::SoapySDROutputGui().

247 {
249  return channelSettings->m_frequencySettings;
250 }
int m_channel
allocated channel (-1 if none)
std::vector< FrequencySetting > m_frequencySettings
tunable elements settings
DeviceSoapySDRParams * m_deviceParams
const ChannelSettings * getTxChannelSettings(uint32_t index)
DeviceSoapySDRShared m_deviceShared
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ handleMessage()

bool SoapySDROutput::handleMessage ( const Message message)
virtual

Implements DeviceSampleSink.

Definition at line 756 of file soapysdroutput.cpp.

References applySettings(), SoapySDROutput::MsgConfigureSoapySDROutput::create(), DeviceSoapySDRShared::MsgReportDeviceArgsChange::create(), DeviceSoapySDRShared::MsgReportDeviceArgsChange::getDeviceArgSettings(), DeviceAPI::getDeviceItemIndex(), SoapySDROutput::MsgConfigureSoapySDROutput::getForce(), DeviceSampleSink::getMessageQueueToGUI(), SoapySDROutput::MsgConfigureSoapySDROutput::getSettings(), SoapySDROutput::MsgStartStop::getStartStop(), DeviceSoapySDRParams::getTxChannelMainTunableElementName(), DeviceAPI::initDeviceEngine(), SoapySDROutputSettings::m_bandwidth, SoapySDROutputSettings::m_centerFrequency, DeviceSoapySDRShared::m_device, m_deviceAPI, SoapySDROutputSettings::m_deviceArgSettings, DeviceSoapySDRShared::m_deviceParams, m_deviceShared, SoapySDROutputSettings::m_devSampleRate, m_settings, SoapySDROutputSettings::m_useReverseAPI, Message::match(), MessageQueue::push(), DeviceAPI::startDeviceEngine(), DeviceAPI::stopDeviceEngine(), and webapiReverseSendStartStop().

757 {
759  {
760  MsgConfigureSoapySDROutput& conf = (MsgConfigureSoapySDROutput&) message;
761  qDebug() << "SoapySDROutput::handleMessage: MsgConfigureSoapySDROutput";
762 
763  if (!applySettings(conf.getSettings(), conf.getForce())) {
764  qDebug("SoapySDROutput::handleMessage: MsgConfigureSoapySDROutput config error");
765  }
766 
767  return true;
768  }
769  else if (MsgStartStop::match(message))
770  {
771  MsgStartStop& cmd = (MsgStartStop&) message;
772  qDebug() << "SoapySDROutput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop");
773 
774  if (cmd.getStartStop())
775  {
777  {
779  }
780  }
781  else
782  {
784  }
785 
787  webapiReverseSendStartStop(cmd.getStartStop());
788  }
789 
790  return true;
791  }
793  {
794  int requestedChannel = m_deviceAPI->getDeviceItemIndex();
795  //DeviceSoapySDRShared::MsgReportBuddyChange& report = (DeviceSoapySDRShared::MsgReportBuddyChange&) message;
797  //bool fromRxBuddy = report.getRxElseTx();
798 
799  double centerFrequency = m_deviceShared.m_device->getFrequency(
800  SOAPY_SDR_TX,
801  requestedChannel,
803 
804  settings.m_centerFrequency = round(centerFrequency/1000.0) * 1000;
805  settings.m_devSampleRate = round(m_deviceShared.m_device->getSampleRate(SOAPY_SDR_TX, requestedChannel));
806  settings.m_bandwidth = round(m_deviceShared.m_device->getBandwidth(SOAPY_SDR_TX, requestedChannel));
807 
808  //SoapySDROutputThread *outputThread = findThread();
809 
810  m_settings = settings;
811 
812  // propagate settings to GUI if any
813  if (getMessageQueueToGUI())
814  {
815  MsgConfigureSoapySDROutput *reportToGUI = MsgConfigureSoapySDROutput::create(m_settings, false);
816  getMessageQueueToGUI()->push(reportToGUI);
817  }
818 
819  return true;
820  }
822  {
824  QMap<QString, QVariant> deviceArgSettings = report.getDeviceArgSettings();
825 
826  for (const auto &oname : m_settings.m_deviceArgSettings.keys())
827  {
828  auto nvalue = deviceArgSettings.find(oname);
829 
830  if (nvalue != deviceArgSettings.end() && (m_settings.m_deviceArgSettings[oname] != *nvalue))
831  {
832  m_settings.m_deviceArgSettings[oname] = *nvalue;
833  qDebug("SoapySDROutput::handleMessage: MsgReportDeviceArgsChange: device argument %s set to %s",
834  oname.toStdString().c_str(), nvalue->toString().toStdString().c_str());
835  }
836  }
837 
838  // propagate settings to GUI if any
839  if (getMessageQueueToGUI())
840  {
842  m_settings.m_deviceArgSettings);
843  getMessageQueueToGUI()->push(reportToGUI);
844  }
845 
846  return true;
847  }
848  else
849  {
850  return false;
851  }
852 }
bool startDeviceEngine()
Start the device engine corresponding to the stream type.
Definition: deviceapi.cpp:253
static MsgConfigureSoapySDROutput * create(const SoapySDROutputSettings &settings, bool force)
void push(Message *message, bool emitSignal=true)
Push message onto queue.
void stopDeviceEngine()
Stop the device engine corresponding to the stream type.
Definition: deviceapi.cpp:266
static MsgReportDeviceArgsChange * create(const QMap< QString, QVariant > &deviceArgSettings)
std::string getTxChannelMainTunableElementName(uint32_t index)
const QMap< QString, QVariant > & getDeviceArgSettings() const
uint32_t getDeviceItemIndex() const
Definition: deviceapi.h:129
bool initDeviceEngine()
Init the device engine corresponding to the stream type.
Definition: deviceapi.cpp:240
DeviceSoapySDRParams * m_deviceParams
static bool match(const Message *message)
Definition: message.cpp:45
SoapySDR::Device * m_device
SoapySDROutputSettings m_settings
bool applySettings(const SoapySDROutputSettings &settings, bool force=false)
DeviceSoapySDRShared m_deviceShared
DeviceAPI * m_deviceAPI
MessageQueue * getMessageQueueToGUI()
void webapiReverseSendStartStop(bool start)
+ Here is the call graph for this function:

◆ hasDCAutoCorrection()

bool SoapySDROutput::hasDCAutoCorrection ( )

Definition at line 339 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getTxChannelSettings(), DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_deviceParams, m_deviceShared, and DeviceSoapySDRParams::ChannelSettings::m_hasDCAutoCorrection.

Referenced by applySettings(), and SoapySDROutputGui::createCorrectionsControl().

340 {
342  return channelSettings->m_hasDCAutoCorrection;
343 }
int m_channel
allocated channel (-1 if none)
bool m_hasDCAutoCorrection
DC offset auto correction flag.
DeviceSoapySDRParams * m_deviceParams
const ChannelSettings * getTxChannelSettings(uint32_t index)
DeviceSoapySDRShared m_deviceShared
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ hasDCCorrectionValue()

bool SoapySDROutput::hasDCCorrectionValue ( )

Definition at line 345 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getTxChannelSettings(), DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_deviceParams, m_deviceShared, and DeviceSoapySDRParams::ChannelSettings::m_hasDCOffsetValue.

Referenced by applySettings(), and SoapySDROutputGui::createCorrectionsControl().

346 {
348  return channelSettings->m_hasDCOffsetValue;
349 }
int m_channel
allocated channel (-1 if none)
bool m_hasDCOffsetValue
DC offset value flag.
DeviceSoapySDRParams * m_deviceParams
const ChannelSettings * getTxChannelSettings(uint32_t index)
DeviceSoapySDRShared m_deviceShared
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ hasIQAutoCorrection()

bool SoapySDROutput::hasIQAutoCorrection ( )
inline

Definition at line 158 of file soapysdroutput.h.

Referenced by SoapySDROutputGui::createCorrectionsControl().

158 { return false; } // not in SoapySDR interface
+ Here is the caller graph for this function:

◆ hasIQCorrectionValue()

bool SoapySDROutput::hasIQCorrectionValue ( )

Definition at line 351 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getTxChannelSettings(), DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_deviceParams, m_deviceShared, and DeviceSoapySDRParams::ChannelSettings::m_hasIQBalanceValue.

Referenced by applySettings(), and SoapySDROutputGui::createCorrectionsControl().

352 {
354  return channelSettings->m_hasIQBalanceValue;
355 }
int m_channel
allocated channel (-1 if none)
DeviceSoapySDRParams * m_deviceParams
const ChannelSettings * getTxChannelSettings(uint32_t index)
DeviceSoapySDRShared m_deviceShared
bool m_hasIQBalanceValue
IQ correction value flag.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init()

void SoapySDROutput::init ( )
virtual

initializations to be done when all collaborating objects are created and possibly connected

Implements DeviceSampleSink.

Definition at line 357 of file soapysdroutput.cpp.

References applySettings(), and m_settings.

358 {
359  applySettings(m_settings, true);
360 }
SoapySDROutputSettings m_settings
bool applySettings(const SoapySDROutputSettings &settings, bool force=false)
+ Here is the call graph for this function:

◆ initDeviceArgSettings()

void SoapySDROutput::initDeviceArgSettings ( SoapySDROutputSettings settings)

Definition at line 321 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getDeviceArgs(), SoapySDROutputSettings::m_deviceArgSettings, DeviceSoapySDRShared::m_deviceParams, and m_deviceShared.

Referenced by SoapySDROutputGui::SoapySDROutputGui().

322 {
323  settings.m_deviceArgSettings.clear();
324 
325  for (const auto &it : m_deviceShared.m_deviceParams->getDeviceArgs())
326  {
327  if (it.type == SoapySDR::ArgInfo::BOOL) {
328  settings.m_deviceArgSettings[QString(it.key.c_str())] = QVariant(it.value == "true");
329  } else if (it.type == SoapySDR::ArgInfo::INT) {
330  settings.m_deviceArgSettings[QString(it.key.c_str())] = QVariant(atoi(it.value.c_str()));
331  } else if (it.type == SoapySDR::ArgInfo::FLOAT) {
332  settings.m_deviceArgSettings[QString(it.key.c_str())] = QVariant(atof(it.value.c_str()));
333  } else if (it.type == SoapySDR::ArgInfo::STRING) {
334  settings.m_deviceArgSettings[QString(it.key.c_str())] = QVariant(it.value.c_str());
335  }
336  }
337 }
DeviceSoapySDRParams * m_deviceParams
const SoapySDR::ArgInfoList & getDeviceArgs() const
int BOOL
Definition: fcdhid.h:37
DeviceSoapySDRShared m_deviceShared
QMap< QString, QVariant > m_deviceArgSettings
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ initGainSettings()

void SoapySDROutput::initGainSettings ( SoapySDROutputSettings settings)

Definition at line 263 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getTxChannelSettings(), DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_device, DeviceSoapySDRShared::m_deviceParams, m_deviceShared, DeviceSoapySDRParams::ChannelSettings::m_gainSettings, SoapySDROutputSettings::m_globalGain, SoapySDROutputSettings::m_individualGains, and updateGains().

Referenced by SoapySDROutputGui::SoapySDROutputGui().

264 {
266  settings.m_individualGains.clear();
267  settings.m_globalGain = 0;
268 
269  for (const auto &it : channelSettings->m_gainSettings) {
270  settings.m_individualGains[QString(it.m_name.c_str())] = 0.0;
271  }
272 
274 }
int m_channel
allocated channel (-1 if none)
void updateGains(SoapySDR::Device *dev, int requestedChannel, SoapySDROutputSettings &settings)
DeviceSoapySDRParams * m_deviceParams
QMap< QString, double > m_individualGains
SoapySDR::Device * m_device
const ChannelSettings * getTxChannelSettings(uint32_t index)
std::vector< GainSetting > m_gainSettings
gain elements settings
DeviceSoapySDRShared m_deviceShared
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ initStreamArgSettings()

void SoapySDROutput::initStreamArgSettings ( SoapySDROutputSettings settings)

Definition at line 302 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getTxChannelSettings(), DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_deviceParams, m_deviceShared, SoapySDROutputSettings::m_streamArgSettings, and DeviceSoapySDRParams::ChannelSettings::m_streamSettingsArgs.

Referenced by SoapySDROutputGui::SoapySDROutputGui().

303 {
305  settings.m_streamArgSettings.clear();
306 
307  for (const auto &it : channelSettings->m_streamSettingsArgs)
308  {
309  if (it.type == SoapySDR::ArgInfo::BOOL) {
310  settings.m_streamArgSettings[QString(it.key.c_str())] = QVariant(it.value == "true");
311  } else if (it.type == SoapySDR::ArgInfo::INT) {
312  settings.m_streamArgSettings[QString(it.key.c_str())] = QVariant(atoi(it.value.c_str()));
313  } else if (it.type == SoapySDR::ArgInfo::FLOAT) {
314  settings.m_streamArgSettings[QString(it.key.c_str())] = QVariant(atof(it.value.c_str()));
315  } else if (it.type == SoapySDR::ArgInfo::STRING) {
316  settings.m_streamArgSettings[QString(it.key.c_str())] = QVariant(it.value.c_str());
317  }
318  }
319 }
int m_channel
allocated channel (-1 if none)
QMap< QString, QVariant > m_streamArgSettings
DeviceSoapySDRParams * m_deviceParams
int BOOL
Definition: fcdhid.h:37
const ChannelSettings * getTxChannelSettings(uint32_t index)
DeviceSoapySDRShared m_deviceShared
SoapySDR::ArgInfoList m_streamSettingsArgs
common stream parameters
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ initTunableElementsSettings()

void SoapySDROutput::initTunableElementsSettings ( SoapySDROutputSettings settings)

Definition at line 276 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getTxChannelSettings(), DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_device, DeviceSoapySDRShared::m_deviceParams, m_deviceShared, DeviceSoapySDRParams::ChannelSettings::m_frequencySettings, SoapySDROutputSettings::m_tunableElements, and updateTunableElements().

Referenced by SoapySDROutputGui::SoapySDROutputGui().

277 {
279  settings.m_tunableElements.clear();
280  bool first = true;
281 
282  for (const auto &it : channelSettings->m_frequencySettings)
283  {
284  if (first)
285  {
286  first = false;
287  continue;
288  }
289 
290  settings.m_tunableElements[QString(it.m_name.c_str())] = 0.0;
291  }
292 
294 }
int m_channel
allocated channel (-1 if none)
QMap< QString, double > m_tunableElements
std::vector< FrequencySetting > m_frequencySettings
tunable elements settings
DeviceSoapySDRParams * m_deviceParams
void updateTunableElements(SoapySDR::Device *dev, int requestedChannel, SoapySDROutputSettings &settings)
SoapySDR::Device * m_device
const ChannelSettings * getTxChannelSettings(uint32_t index)
DeviceSoapySDRShared m_deviceShared
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isAGCSupported()

bool SoapySDROutput::isAGCSupported ( )

Definition at line 222 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getTxChannelSettings(), DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_deviceParams, m_deviceShared, and DeviceSoapySDRParams::ChannelSettings::m_hasAGC.

Referenced by SoapySDROutputGui::createGlobalGainControl().

223 {
225  return channelSettings->m_hasAGC;
226 }
int m_channel
allocated channel (-1 if none)
DeviceSoapySDRParams * m_deviceParams
const ChannelSettings * getTxChannelSettings(uint32_t index)
DeviceSoapySDRShared m_deviceShared
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ moveThreadToBuddy()

void SoapySDROutput::moveThreadToBuddy ( )
private

Definition at line 394 of file soapysdroutput.cpp.

References DeviceAPI::getSinkBuddies(), m_deviceAPI, m_thread, and setThread().

Referenced by closeDevice().

395 {
396  const std::vector<DeviceAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
397  std::vector<DeviceAPI*>::const_iterator it = sinkBuddies.begin();
398 
399  for (; it != sinkBuddies.end(); ++it)
400  {
401  SoapySDROutput *buddySink = ((DeviceSoapySDRShared*) (*it)->getBuddySharedPtr())->m_sink;
402 
403  if (buddySink)
404  {
405  buddySink->setThread(m_thread);
406  m_thread = 0; // zero for others
407  }
408  }
409 }
const std::vector< DeviceAPI * > & getSinkBuddies() const
Definition: deviceapi.h:166
DeviceAPI * m_deviceAPI
void setThread(SoapySDROutputThread *thread)
SoapySDROutputThread * m_thread
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ networkManagerFinished

void SoapySDROutput::networkManagerFinished ( QNetworkReply *  reply)
privateslot

Definition at line 1929 of file soapysdroutput.cpp.

Referenced by ~SoapySDROutput().

1930 {
1931  QNetworkReply::NetworkError replyError = reply->error();
1932 
1933  if (replyError)
1934  {
1935  qWarning() << "SoapySDROutput::networkManagerFinished:"
1936  << " error(" << (int) replyError
1937  << "): " << replyError
1938  << ": " << reply->errorString();
1939  return;
1940  }
1941 
1942  QString answer = reply->readAll();
1943  answer.chop(1); // remove last \n
1944  qDebug("SoapySDROutput::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
1945 }
+ Here is the caller graph for this function:

◆ openDevice()

bool SoapySDROutput::openDevice ( )
private

Definition at line 75 of file soapysdroutput.cpp.

References DeviceAPI::getBuddySharedPtr(), DeviceAPI::getDeviceItemIndex(), DeviceAPI::getHardwareUserArguments(), DeviceAPI::getSamplingDeviceSequence(), DeviceAPI::getSinkBuddies(), DeviceAPI::getSourceBuddies(), DeviceSoapySDR::instance(), DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_device, m_deviceAPI, DeviceSoapySDRShared::m_deviceParams, m_deviceShared, SoapySDROutputSettings::m_devSampleRate, SoapySDROutputSettings::m_log2Interp, DeviceSampleSink::m_sampleSourceFifo, m_settings, DeviceSoapySDRShared::m_sink, DeviceSoapySDR::openSoapySDR(), SampleSourceFifo::resize(), and DeviceAPI::setBuddySharedPtr().

76 {
78 
79  // look for Tx buddies and get reference to the device object
80  if (m_deviceAPI->getSinkBuddies().size() > 0) // look sink sibling first
81  {
82  qDebug("SoapySDROutput::openDevice: look in Tx buddies");
83 
84  DeviceAPI *sinkBuddy = m_deviceAPI->getSinkBuddies()[0];
85  DeviceSoapySDRShared *deviceSoapySDRShared = (DeviceSoapySDRShared*) sinkBuddy->getBuddySharedPtr();
86 
87  if (deviceSoapySDRShared == 0)
88  {
89  qCritical("SoapySDROutput::openDevice: the sink buddy shared pointer is null");
90  return false;
91  }
92 
93  SoapySDR::Device *device = deviceSoapySDRShared->m_device;
94 
95  if (device == 0)
96  {
97  qCritical("SoapySDROutput::openDevice: cannot get device pointer from Tx buddy");
98  return false;
99  }
100 
101  m_deviceShared.m_device = device;
102  m_deviceShared.m_deviceParams = deviceSoapySDRShared->m_deviceParams;
103  }
104  // look for Rx buddies and get reference to the device object
105  else if (m_deviceAPI->getSourceBuddies().size() > 0) // then source
106  {
107  qDebug("SoapySDROutput::openDevice: look in Rx buddies");
108 
109  DeviceAPI *sourceBuddy = m_deviceAPI->getSourceBuddies()[0];
110  DeviceSoapySDRShared *deviceSoapySDRShared = (DeviceSoapySDRShared*) sourceBuddy->getBuddySharedPtr();
111 
112  if (deviceSoapySDRShared == 0)
113  {
114  qCritical("SoapySDROutput::openDevice: the source buddy shared pointer is null");
115  return false;
116  }
117 
118  SoapySDR::Device *device = deviceSoapySDRShared->m_device;
119 
120  if (device == 0)
121  {
122  qCritical("SoapySDROutput::openDevice: cannot get device pointer from Rx buddy");
123  return false;
124  }
125 
126  m_deviceShared.m_device = device;
127  m_deviceShared.m_deviceParams = deviceSoapySDRShared->m_deviceParams;
128  }
129  // There are no buddies then create the first BladeRF2 device
130  else
131  {
132  qDebug("SoapySDROutput::openDevice: open device here");
133  DeviceSoapySDR& deviceSoapySDR = DeviceSoapySDR::instance();
135 
137  {
138  qCritical("SoapySDROutput::openDevice: cannot open SoapySDR device");
139  return false;
140  }
141 
143  }
144 
145  m_deviceShared.m_channel = m_deviceAPI->getDeviceItemIndex(); // publicly allocate channel
146  m_deviceShared.m_sink = this;
147  m_deviceAPI->setBuddySharedPtr(&m_deviceShared); // propagate common parameters to API
148  return true;
149 }
int m_channel
allocated channel (-1 if none)
const std::vector< DeviceAPI * > & getSinkBuddies() const
Definition: deviceapi.h:166
static DeviceSoapySDR & instance()
uint32_t getDeviceItemIndex() const
Definition: deviceapi.h:129
const QString & getHardwareUserArguments() const
Definition: deviceapi.h:124
void * getBuddySharedPtr() const
Definition: deviceapi.h:161
DeviceSoapySDRParams * m_deviceParams
void setBuddySharedPtr(void *ptr)
Definition: deviceapi.h:162
SoapySDR::Device * m_device
SoapySDROutputSettings m_settings
void resize(uint32_t size)
SoapySDR::Device * openSoapySDR(uint32_t sequence, const QString &hardwareUserArguments)
SampleSourceFifo m_sampleSourceFifo
const std::vector< DeviceAPI * > & getSourceBuddies() const
Definition: deviceapi.h:165
DeviceSoapySDRShared m_deviceShared
DeviceAPI * m_deviceAPI
uint32_t getSamplingDeviceSequence() const
Definition: deviceapi.h:123
+ Here is the call graph for this function:

◆ serialize()

QByteArray SoapySDROutput::serialize ( ) const
virtual

Implements DeviceSampleSink.

Definition at line 639 of file soapysdroutput.cpp.

References m_settings, and SoapySDROutputSettings::serialize().

640 {
641  return m_settings.serialize();
642 }
SoapySDROutputSettings m_settings
+ Here is the call graph for this function:

◆ setCenterFrequency()

void SoapySDROutput::setCenterFrequency ( qint64  centerFrequency)
virtual

Implements DeviceSampleSink.

Definition at line 682 of file soapysdroutput.cpp.

References SoapySDROutput::MsgConfigureSoapySDROutput::create(), SoapySDROutputSettings::m_centerFrequency, DeviceSampleSink::m_guiMessageQueue, DeviceSampleSink::m_inputMessageQueue, m_settings, and MessageQueue::push().

683 {
685  settings.m_centerFrequency = centerFrequency;
686 
687  MsgConfigureSoapySDROutput* message = MsgConfigureSoapySDROutput::create(settings, false);
688  m_inputMessageQueue.push(message);
689 
690  if (m_guiMessageQueue)
691  {
692  MsgConfigureSoapySDROutput* messageToGUI = MsgConfigureSoapySDROutput::create(settings, false);
693  m_guiMessageQueue->push(messageToGUI);
694  }
695 }
static MsgConfigureSoapySDROutput * create(const SoapySDROutputSettings &settings, bool force)
void push(Message *message, bool emitSignal=true)
Push message onto queue.
MessageQueue m_inputMessageQueue
Input queue to the sink.
SoapySDROutputSettings m_settings
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
+ Here is the call graph for this function:

◆ setDeviceCenterFrequency()

bool SoapySDROutput::setDeviceCenterFrequency ( SoapySDR::Device *  dev,
int  requestedChannel,
quint64  freq_hz,
int  loPpmTenths 
)
private

Definition at line 697 of file soapysdroutput.cpp.

References DeviceSoapySDRParams::getTxChannelMainTunableElementName(), DeviceSoapySDRShared::m_deviceParams, and m_deviceShared.

Referenced by applySettings().

698 {
699  qint64 df = ((qint64)freq_hz * loPpmTenths) / 10000000LL;
700  freq_hz += df;
701 
702  try
703  {
704  dev->setFrequency(SOAPY_SDR_TX,
705  requestedChannel,
707  freq_hz);
708  qDebug("SoapySDROutput::setDeviceCenterFrequency: setFrequency(%llu)", freq_hz);
709  return true;
710  }
711  catch (const std::exception &ex)
712  {
713  qCritical("SoapySDROutput::applySettings: could not set frequency: %llu: %s", freq_hz, ex.what());
714  return false;
715  }
716 }
std::string getTxChannelMainTunableElementName(uint32_t index)
DeviceSoapySDRParams * m_deviceParams
DeviceSoapySDRShared m_deviceShared
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setMessageQueueToGUI()

virtual void SoapySDROutput::setMessageQueueToGUI ( MessageQueue queue)
inlinevirtual

Implements DeviceSampleSink.

Definition at line 133 of file soapysdroutput.h.

Referenced by SoapySDROutputGui::SoapySDROutputGui().

133 { m_guiMessageQueue = queue; }
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
+ Here is the caller graph for this function:

◆ setSampleRate()

virtual void SoapySDROutput::setSampleRate ( int  sampleRate)
inlinevirtual

For when the sink sample rate is set externally.

Implements DeviceSampleSink.

Definition at line 136 of file soapysdroutput.h.

References leansdr::max(), and leansdr::min().

136 { (void) sampleRate; }
+ Here is the call graph for this function:

◆ setThread()

void SoapySDROutput::setThread ( SoapySDROutputThread thread)
inline

Definition at line 128 of file soapysdroutput.h.

Referenced by moveThreadToBuddy().

128 { m_thread = thread; }
SoapySDROutputThread * m_thread
+ Here is the caller graph for this function:

◆ start()

bool SoapySDROutput::start ( )
virtual

Implements DeviceSampleSink.

Definition at line 411 of file soapysdroutput.cpp.

References findThread(), DeviceAPI::getDeviceItemIndex(), SoapySDROutputThread::getFifo(), SoapySDROutputThread::getLog2Interpolation(), SoapySDROutputThread::getNbChannels(), DeviceAPI::getSinkBuddies(), i, DeviceSoapySDRShared::m_device, m_deviceAPI, m_deviceShared, SoapySDROutputSettings::m_devSampleRate, SoapySDROutputSettings::m_log2Interp, m_running, DeviceSampleSink::m_sampleSourceFifo, m_settings, m_thread, SoapySDROutputThread::setFifo(), SoapySDROutputThread::setLog2Interpolation(), SoapySDROutputThread::setSampleRate(), SoapySDROutputThread::startWork(), and SoapySDROutputThread::stopWork().

412 {
413  // There is a single thread per physical device (Tx side). This thread is unique and referenced by a unique
414  // buddy in the group of sink buddies associated with this physical device.
415  //
416  // This start method is responsible for managing the thread and channel enabling when the streaming of a Tx channel is started
417  //
418  // It checks the following conditions
419  // - the thread is allocated or not (by itself or one of its buddies). If it is it grabs the thread pointer.
420  // - the requested channel is the first (0) or the following
421  //
422  // There are two possible working modes:
423  // - Single Output (SO) with only one channel streaming. This HAS to be channel 0.
424  // - Multiple Output (MO) with two or more channels. It MUST be in this configuration if any channel other than 0
425  // is used. For example when we will run with only channel 2 streaming from the client perspective the channels 0 and 1
426  // will actually be enabled and streaming but zero samples will be sent to it.
427  //
428  // It manages the transition form SO where only one channel (the first or channel 0) should be running to the
429  // Multiple Output (MO) if the requested channel is 1 or more. More generally it checks if the requested channel is within the current
430  // channel range allocated in the thread or past it. To perform the transition it stops the thread, deletes it and creates a new one.
431  // It marks the thread as needing start.
432  //
433  // If the requested channel is within the thread channel range (this thread being already allocated) it simply removes its FIFO reference
434  // so that the samples are not taken from the FIFO anymore and leaves the thread unchanged (no stop, no delete/new)
435  //
436  // If there is no thread allocated it creates a new one with a number of channels that fits the requested channel. That is
437  // 1 if channel 0 is requested (SO mode) and 3 if channel 2 is requested (MO mode). It marks the thread as needing start.
438  //
439  // Eventually it registers the FIFO in the thread. If the thread has to be started it enables the channels up to the number of channels
440  // allocated in the thread and starts the thread.
441  //
442  // Note: this is quite similar to the BladeRF2 start handling. The main difference is that the channel allocation (enabling) process is
443  // done in the thread object.
444 
445 
447  {
448  qDebug("SoapySDROutput::start: no device object");
449  return false;
450  }
451 
452  int requestedChannel = m_deviceAPI->getDeviceItemIndex();
453  SoapySDROutputThread *soapySDROutputThread = findThread();
454  bool needsStart = false;
455 
456  if (soapySDROutputThread) // if thread is already allocated
457  {
458  qDebug("SoapySDROutput::start: thread is already allocated");
459 
460  int nbOriginalChannels = soapySDROutputThread->getNbChannels();
461 
462  if (requestedChannel+1 > nbOriginalChannels) // expansion by deleting and re-creating the thread
463  {
464  qDebug("SoapySDROutput::start: expand channels. Re-allocate thread and take ownership");
465 
466  SampleSourceFifo **fifos = new SampleSourceFifo*[nbOriginalChannels];
467  unsigned int *log2Interps = new unsigned int[nbOriginalChannels];
468 
469  for (int i = 0; i < nbOriginalChannels; i++) // save original FIFO references and data
470  {
471  fifos[i] = soapySDROutputThread->getFifo(i);
472  log2Interps[i] = soapySDROutputThread->getLog2Interpolation(i);
473  }
474 
475  soapySDROutputThread->stopWork();
476  delete soapySDROutputThread;
477  soapySDROutputThread = new SoapySDROutputThread(m_deviceShared.m_device, requestedChannel+1);
478  m_thread = soapySDROutputThread; // take ownership
479 
480  for (int i = 0; i < nbOriginalChannels; i++) // restore original FIFO references
481  {
482  soapySDROutputThread->setFifo(i, fifos[i]);
483  soapySDROutputThread->setLog2Interpolation(i, log2Interps[i]);
484  }
485 
486  // remove old thread address from buddies (reset in all buddies). The address being held only in the owning sink.
487  const std::vector<DeviceAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
488  std::vector<DeviceAPI*>::const_iterator it = sinkBuddies.begin();
489 
490  for (; it != sinkBuddies.end(); ++it) {
491  ((DeviceSoapySDRShared*) (*it)->getBuddySharedPtr())->m_sink->setThread(0);
492  }
493 
494  delete[] log2Interps;
495  delete[] fifos;
496 
497  needsStart = true;
498  }
499  else
500  {
501  qDebug("SoapySDROutput::start: keep buddy thread");
502  }
503  }
504  else // first allocation
505  {
506  qDebug("SoapySDROutput::start: allocate thread and take ownership");
507  soapySDROutputThread = new SoapySDROutputThread(m_deviceShared.m_device, requestedChannel+1);
508  m_thread = soapySDROutputThread; // take ownership
509  needsStart = true;
510  }
511 
512  soapySDROutputThread->setFifo(requestedChannel, &m_sampleSourceFifo);
513  soapySDROutputThread->setLog2Interpolation(requestedChannel, m_settings.m_log2Interp);
514 
515  if (needsStart)
516  {
517  qDebug("SoapySDROutput::start: (re)sart buddy thread");
518  soapySDROutputThread->setSampleRate(m_settings.m_devSampleRate);
519  soapySDROutputThread->startWork();
520  }
521 
522  qDebug("SoapySDROutput::start: started");
523  m_running = true;
524 
525  return true;
526 }
unsigned int getLog2Interpolation(unsigned int channel) const
const std::vector< DeviceAPI * > & getSinkBuddies() const
Definition: deviceapi.h:166
uint32_t getDeviceItemIndex() const
Definition: deviceapi.h:129
void setSampleRate(unsigned int sampleRate)
unsigned int getNbChannels() const
int32_t i
Definition: decimators.h:244
SoapySDR::Device * m_device
SoapySDROutputSettings m_settings
void setFifo(unsigned int channel, SampleSourceFifo *sampleFifo)
SoapySDROutputThread * findThread()
SampleSourceFifo m_sampleSourceFifo
DeviceSoapySDRShared m_deviceShared
DeviceAPI * m_deviceAPI
SampleSourceFifo * getFifo(unsigned int channel)
void setLog2Interpolation(unsigned int channel, unsigned int log2_interp)
SoapySDROutputThread * m_thread
+ Here is the call graph for this function:

◆ stop()

void SoapySDROutput::stop ( )
virtual

Implements DeviceSampleSink.

Definition at line 528 of file soapysdroutput.cpp.

References applySettings(), findThread(), DeviceAPI::getDeviceItemIndex(), SoapySDROutputThread::getFifo(), SoapySDROutputThread::getLog2Interpolation(), SoapySDROutputThread::getNbChannels(), DeviceAPI::getSinkBuddies(), i, DeviceSoapySDRShared::m_device, m_deviceAPI, m_deviceShared, m_running, m_settings, m_thread, SoapySDROutputThread::setFifo(), SoapySDROutputThread::setLog2Interpolation(), SoapySDROutputThread::startWork(), and SoapySDROutputThread::stopWork().

Referenced by closeDevice(), and ~SoapySDROutput().

529 {
530  // This stop method is responsible for managing the thread and channel disabling when the streaming of
531  // a Tx channel is stopped
532  //
533  // If the thread is currently managing only one channel (SO mode). The thread can be just stopped and deleted.
534  // Then the channel is closed (disabled).
535  //
536  // If the thread is currently managing many channels (MO mode) and we are removing the last channel. The transition
537  // from MO to SO or reduction of MO size is handled by stopping the thread, deleting it and creating a new one
538  // with the maximum number of channels needed if (and only if) there is still a channel active.
539  //
540  // If the thread is currently managing many channels (MO mode) but the channel being stopped is not the last
541  // channel then the FIFO reference is simply removed from the thread so that this FIFO will not be used anymore.
542  // In this case the channel is not closed (this is managed in the thread object) so that other channels can continue with the
543  // same configuration. The device continues streaming on this channel but the samples are set to all zeros.
544 
545  if (!m_running) {
546  return;
547  }
548 
549  int requestedChannel = m_deviceAPI->getDeviceItemIndex();
550  SoapySDROutputThread *soapySDROutputThread = findThread();
551 
552  if (soapySDROutputThread == 0) { // no thread allocated
553  return;
554  }
555 
556  int nbOriginalChannels = soapySDROutputThread->getNbChannels();
557 
558  if (nbOriginalChannels == 1) // SO mode => just stop and delete the thread
559  {
560  qDebug("SoapySDROutput::stop: SO mode. Just stop and delete the thread");
561  soapySDROutputThread->stopWork();
562  delete soapySDROutputThread;
563  m_thread = 0;
564 
565  // remove old thread address from buddies (reset in all buddies)
566  const std::vector<DeviceAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
567  std::vector<DeviceAPI*>::const_iterator it = sinkBuddies.begin();
568 
569  for (; it != sinkBuddies.end(); ++it) {
570  ((DeviceSoapySDRShared*) (*it)->getBuddySharedPtr())->m_sink->setThread(0);
571  }
572  }
573  else if (requestedChannel == nbOriginalChannels - 1) // remove last MO channel => reduce by deleting and re-creating the thread
574  {
575  qDebug("SoapySDROutput::stop: MO mode. Reduce by deleting and re-creating the thread");
576  soapySDROutputThread->stopWork();
577  SampleSourceFifo **fifos = new SampleSourceFifo*[nbOriginalChannels-1];
578  unsigned int *log2Interps = new unsigned int[nbOriginalChannels-1];
579  int highestActiveChannelIndex = -1;
580 
581  for (int i = 0; i < nbOriginalChannels-1; i++) // save original FIFO references
582  {
583  fifos[i] = soapySDROutputThread->getFifo(i);
584 
585  if ((soapySDROutputThread->getFifo(i) != 0) && (i > highestActiveChannelIndex)) {
586  highestActiveChannelIndex = i;
587  }
588 
589  log2Interps[i] = soapySDROutputThread->getLog2Interpolation(i);
590  }
591 
592  delete soapySDROutputThread;
593  m_thread = 0;
594 
595  if (highestActiveChannelIndex >= 0)
596  {
597  soapySDROutputThread = new SoapySDROutputThread(m_deviceShared.m_device, highestActiveChannelIndex+1);
598  m_thread = soapySDROutputThread; // take ownership
599 
600  for (int i = 0; i < nbOriginalChannels-1; i++) // restore original FIFO references
601  {
602  soapySDROutputThread->setFifo(i, fifos[i]);
603  soapySDROutputThread->setLog2Interpolation(i, log2Interps[i]);
604  }
605  }
606  else
607  {
608  qDebug("SoapySDROutput::stop: do not re-create thread as there are no more FIFOs active");
609  }
610 
611  // remove old thread address from buddies (reset in all buddies). The address being held only in the owning sink.
612  const std::vector<DeviceAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
613  std::vector<DeviceAPI*>::const_iterator it = sinkBuddies.begin();
614 
615  for (; it != sinkBuddies.end(); ++it) {
616  ((DeviceSoapySDRShared*) (*it)->getBuddySharedPtr())->m_sink->setThread(0);
617  }
618 
619  if (highestActiveChannelIndex >= 0)
620  {
621  qDebug("SoapySDROutput::stop: restarting the thread");
622  soapySDROutputThread->startWork();
623  }
624 
625  delete[] log2Interps;
626  delete[] fifos;
627  }
628  else // remove channel from existing thread
629  {
630  qDebug("SoapySDROutput::stop: MO mode. Not changing MO configuration. Just remove FIFO reference");
631  soapySDROutputThread->setFifo(requestedChannel, 0); // remove FIFO
632  }
633 
634  applySettings(m_settings, true); // re-apply forcibly to set sample rate with the new number of channels
635 
636  m_running = false;
637 }
unsigned int getLog2Interpolation(unsigned int channel) const
const std::vector< DeviceAPI * > & getSinkBuddies() const
Definition: deviceapi.h:166
uint32_t getDeviceItemIndex() const
Definition: deviceapi.h:129
unsigned int getNbChannels() const
int32_t i
Definition: decimators.h:244
SoapySDR::Device * m_device
SoapySDROutputSettings m_settings
void setFifo(unsigned int channel, SampleSourceFifo *sampleFifo)
bool applySettings(const SoapySDROutputSettings &settings, bool force=false)
SoapySDROutputThread * findThread()
DeviceSoapySDRShared m_deviceShared
DeviceAPI * m_deviceAPI
SampleSourceFifo * getFifo(unsigned int channel)
void setLog2Interpolation(unsigned int channel, unsigned int log2_interp)
SoapySDROutputThread * m_thread
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ updateGains()

void SoapySDROutput::updateGains ( SoapySDR::Device *  dev,
int  requestedChannel,
SoapySDROutputSettings settings 
)
private

Definition at line 718 of file soapysdroutput.cpp.

References SoapySDROutputSettings::m_globalGain, and SoapySDROutputSettings::m_individualGains.

Referenced by applySettings(), and initGainSettings().

719 {
720  if (dev == 0) {
721  return;
722  }
723 
724  try
725  {
726  settings.m_globalGain = round(dev->getGain(SOAPY_SDR_TX, requestedChannel));
727 
728  for (const auto &name : settings.m_individualGains.keys()) {
729  settings.m_individualGains[name] = dev->getGain(SOAPY_SDR_TX, requestedChannel, name.toStdString());
730  }
731  }
732  catch (const std::exception &ex)
733  {
734  qCritical("SoapySDROutput::updateGains: caught exception: %s", ex.what());
735  }
736 }
QMap< QString, double > m_individualGains
+ Here is the caller graph for this function:

◆ updateTunableElements()

void SoapySDROutput::updateTunableElements ( SoapySDR::Device *  dev,
int  requestedChannel,
SoapySDROutputSettings settings 
)
private

Definition at line 738 of file soapysdroutput.cpp.

References SoapySDROutputSettings::m_tunableElements.

Referenced by initTunableElementsSettings().

739 {
740  if (dev == 0) {
741  return;
742  }
743 
744  try
745  {
746  for (const auto &name : settings.m_tunableElements.keys()) {
747  settings.m_tunableElements[name] = dev->getFrequency(SOAPY_SDR_TX, requestedChannel, name.toStdString());
748  }
749  }
750  catch (const std::exception &ex)
751  {
752  qCritical("SoapySDROutput::updateTunableElements: caught exception: %s", ex.what());
753  }
754 }
QMap< QString, double > m_tunableElements
+ Here is the caller graph for this function:

◆ webapiFormatArgInfo()

void SoapySDROutput::webapiFormatArgInfo ( const SoapySDR::ArgInfo &  arg,
SWGSDRangel::SWGArgInfo argInfo 
)
private

Definition at line 1783 of file soapysdroutput.cpp.

References SWGSDRangel::SWGArgInfo::getOptionNames(), SWGSDRangel::SWGArgInfo::getRange(), SWGSDRangel::SWGArgInfo::getValueOptions(), SWGSDRangel::SWGArgInfo::setDescription(), SWGSDRangel::SWGArgInfo::setKey(), SWGSDRangel::SWGRangeFloat::setMax(), SWGSDRangel::SWGRangeFloat::setMin(), SWGSDRangel::SWGArgInfo::setName(), SWGSDRangel::SWGArgInfo::setOptionNames(), SWGSDRangel::SWGArgInfo::setRange(), SWGSDRangel::SWGArgInfo::setUnits(), SWGSDRangel::SWGArgInfo::setValueOptions(), SWGSDRangel::SWGArgInfo::setValueString(), and SWGSDRangel::SWGArgInfo::setValueType().

Referenced by webapiFormatDeviceReport().

1784 {
1785  argInfo->setKey(new QString(arg.key.c_str()));
1786 
1787  if (arg.type == SoapySDR::ArgInfo::BOOL) {
1788  argInfo->setValueType(new QString("bool"));
1789  } else if (arg.type == SoapySDR::ArgInfo::INT) {
1790  argInfo->setValueType(new QString("int"));
1791  } else if (arg.type == SoapySDR::ArgInfo::FLOAT) {
1792  argInfo->setValueType(new QString("float"));
1793  } else {
1794  argInfo->setValueType(new QString("string"));
1795  }
1796 
1797  argInfo->setValueString(new QString(arg.value.c_str()));
1798  argInfo->setName(new QString(arg.name.c_str()));
1799  argInfo->setDescription(new QString(arg.description.c_str()));
1800  argInfo->setUnits(new QString(arg.units.c_str()));
1801 
1802  if ((arg.range.minimum() != 0.0) || (arg.range.maximum() != 0.0))
1803  {
1804  argInfo->setRange(new SWGSDRangel::SWGRangeFloat());
1805  argInfo->getRange()->setMin(arg.range.minimum());
1806  argInfo->getRange()->setMax(arg.range.maximum());
1807  }
1808 
1809  argInfo->setValueOptions(new QList<QString*>);
1810 
1811  for (const auto itOpt : arg.options) {
1812  argInfo->getValueOptions()->append(new QString(itOpt.c_str()));
1813  }
1814 
1815  argInfo->setOptionNames(new QList<QString*>);
1816 
1817  for (const auto itOpt : arg.optionNames) {
1818  argInfo->getOptionNames()->append(new QString(itOpt.c_str()));
1819  }
1820 }
QList< QString * > * getValueOptions()
Definition: SWGArgInfo.cpp:263
QList< QString * > * getOptionNames()
Definition: SWGArgInfo.cpp:273
void setName(QString *name)
Definition: SWGArgInfo.cpp:227
void setValueOptions(QList< QString *> *value_options)
Definition: SWGArgInfo.cpp:267
void setRange(SWGRangeFloat *range)
Definition: SWGArgInfo.cpp:257
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
void setValueString(QString *value_string)
Definition: SWGArgInfo.cpp:217
void setValueType(QString *value_type)
Definition: SWGArgInfo.cpp:207
void setKey(QString *key)
Definition: SWGArgInfo.cpp:197
SWGRangeFloat * getRange()
Definition: SWGArgInfo.cpp:253
int BOOL
Definition: fcdhid.h:37
void setUnits(QString *units)
Definition: SWGArgInfo.cpp:247
void setDescription(QString *description)
Definition: SWGArgInfo.cpp:237
void setOptionNames(QList< QString *> *option_names)
Definition: SWGArgInfo.cpp:277
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiFormatArgValue()

void SoapySDROutput::webapiFormatArgValue ( const QVariant &  v,
SWGSDRangel::SWGArgValue argValue 
)
private

Definition at line 1759 of file soapysdroutput.cpp.

References arg(), SWGSDRangel::SWGArgValue::setValueString(), and SWGSDRangel::SWGArgValue::setValueType().

Referenced by webapiFormatDeviceSettings().

1760 {
1761  if (v.type() == QVariant::Bool)
1762  {
1763  argValue->setValueType(new QString("bool"));
1764  argValue->setValueString(new QString(v.toBool() ? "1" : "0"));
1765  }
1766  else if (v.type() == QVariant::Int)
1767  {
1768  argValue->setValueType(new QString("int"));
1769  argValue->setValueString(new QString(tr("%1").arg(v.toInt())));
1770  }
1771  else if (v.type() == QVariant::Double)
1772  {
1773  argValue->setValueType(new QString("float"));
1774  argValue->setValueString(new QString(tr("%1").arg(v.toDouble())));
1775  }
1776  else
1777  {
1778  argValue->setValueType(new QString("string"));
1779  argValue->setValueString(new QString(v.toString()));
1780  }
1781 }
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
void setValueString(QString *value_string)
void setValueType(QString *value_type)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiFormatDeviceReport()

void SoapySDROutput::webapiFormatDeviceReport ( SWGSDRangel::SWGDeviceReport response)
private

Definition at line 1637 of file soapysdroutput.cpp.

References SWGSDRangel::SWGSoapySDRReport::getAntennas(), SWGSDRangel::SWGSoapySDRReport::getBandwidthsRanges(), DeviceSoapySDRParams::getDeviceArgs(), SWGSDRangel::SWGSoapySDRReport::getDeviceSettingsArgs(), SWGSDRangel::SWGSoapySDRReport::getFrequencySettings(), SWGSDRangel::SWGSoapySDRReport::getFrequencySettingsArgs(), SWGSDRangel::SWGSoapySDRReport::getGainRange(), SWGSDRangel::SWGSoapySDRReport::getGainSettings(), SWGSDRangel::SWGSoapySDRReport::getRatesRanges(), SWGSDRangel::SWGDeviceReport::getSoapySdrOutputReport(), SWGSDRangel::SWGSoapySDRReport::getStreamSettingsArgs(), DeviceSoapySDRParams::getTxChannelSettings(), DeviceSoapySDRParams::ChannelSettings::m_antennas, DeviceSoapySDRParams::ChannelSettings::m_bandwidthsRanges, DeviceSoapySDRShared::m_channel, DeviceSoapySDRShared::m_deviceParams, m_deviceShared, DeviceSoapySDRParams::ChannelSettings::m_frequencySettings, DeviceSoapySDRParams::ChannelSettings::m_frequencySettingsArgs, DeviceSoapySDRParams::ChannelSettings::m_gainRange, DeviceSoapySDRParams::ChannelSettings::m_gainSettings, DeviceSoapySDRParams::ChannelSettings::m_hasAGC, DeviceSoapySDRParams::ChannelSettings::m_hasDCAutoCorrection, DeviceSoapySDRParams::ChannelSettings::m_hasDCOffsetValue, DeviceSoapySDRParams::ChannelSettings::m_hasFrequencyCorrectionValue, DeviceSoapySDRParams::ChannelSettings::m_hasIQBalanceValue, DeviceSoapySDRParams::ChannelSettings::m_ratesRanges, DeviceSoapySDRParams::ChannelSettings::m_streamSettingsArgs, SWGSDRangel::SWGSoapySDRReport::setAntennas(), SWGSDRangel::SWGSoapySDRReport::setBandwidthsRanges(), SWGSDRangel::SWGSoapySDRReport::setDeviceSettingsArgs(), SWGSDRangel::SWGSoapySDRReport::setFrequencySettings(), SWGSDRangel::SWGSoapySDRReport::setFrequencySettingsArgs(), SWGSDRangel::SWGSoapySDRReport::setGainRange(), SWGSDRangel::SWGSoapySDRReport::setGainSettings(), SWGSDRangel::SWGSoapySDRReport::setHasAgc(), SWGSDRangel::SWGSoapySDRReport::setHasDcAutoCorrection(), SWGSDRangel::SWGSoapySDRReport::setHasDcOffsetValue(), SWGSDRangel::SWGSoapySDRReport::setHasFrequencyCorrectionValue(), SWGSDRangel::SWGSoapySDRReport::setHasIqBalanceValue(), SWGSDRangel::SWGRangeFloat::setMax(), SWGSDRangel::SWGRangeFloat::setMin(), SWGSDRangel::SWGSoapySDRReport::setRatesRanges(), SWGSDRangel::SWGSoapySDRReport::setStreamSettingsArgs(), and webapiFormatArgInfo().

Referenced by webapiReportGet().

1638 {
1640 
1641  response.getSoapySdrOutputReport()->setDeviceSettingsArgs(new QList<SWGSDRangel::SWGArgInfo*>);
1642 
1643  for (const auto itArg : m_deviceShared.m_deviceParams->getDeviceArgs())
1644  {
1647  }
1648 
1649  response.getSoapySdrOutputReport()->setStreamSettingsArgs(new QList<SWGSDRangel::SWGArgInfo*>);
1650 
1651  for (const auto itArg : channelSettings->m_streamSettingsArgs)
1652  {
1655  }
1656 
1657  response.getSoapySdrOutputReport()->setFrequencySettingsArgs(new QList<SWGSDRangel::SWGArgInfo*>);
1658 
1659  for (const auto itArg : channelSettings->m_frequencySettingsArgs)
1660  {
1663  }
1664 
1665  response.getSoapySdrOutputReport()->setHasAgc(channelSettings->m_hasAGC ? 1 : 0);
1666  response.getSoapySdrOutputReport()->setHasDcAutoCorrection(channelSettings->m_hasDCAutoCorrection ? 1 : 0);
1667  response.getSoapySdrOutputReport()->setHasDcOffsetValue(channelSettings->m_hasDCOffsetValue ? 1 : 0);
1669  response.getSoapySdrOutputReport()->setHasIqBalanceValue(channelSettings->m_hasIQBalanceValue ? 1 : 0);
1670 
1671  if (channelSettings->m_antennas.size() != 0)
1672  {
1673  response.getSoapySdrOutputReport()->setAntennas(new QList<QString *>);
1674 
1675  for (const auto itAntenna : channelSettings->m_antennas) {
1676  response.getSoapySdrOutputReport()->getAntennas()->append(new QString(itAntenna.c_str()));
1677  }
1678  }
1679 
1680  if ((channelSettings->m_gainRange.maximum() != 0.0) || (channelSettings->m_gainRange.minimum() != 0.0))
1681  {
1683  response.getSoapySdrOutputReport()->getGainRange()->setMin(channelSettings->m_gainRange.minimum());
1684  response.getSoapySdrOutputReport()->getGainRange()->setMax(channelSettings->m_gainRange.maximum());
1685  }
1686 
1687  if (channelSettings->m_gainSettings.size() != 0)
1688  {
1689  response.getSoapySdrOutputReport()->setGainSettings(new QList<SWGSDRangel::SWGSoapySDRGainSetting*>);
1690 
1691  for (const auto itGain : channelSettings->m_gainSettings)
1692  {
1694  response.getSoapySdrOutputReport()->getGainSettings()->back()->setRange(new SWGSDRangel::SWGRangeFloat());
1695  response.getSoapySdrOutputReport()->getGainSettings()->back()->getRange()->setMin(itGain.m_range.minimum());
1696  response.getSoapySdrOutputReport()->getGainSettings()->back()->getRange()->setMax(itGain.m_range.maximum());
1697  response.getSoapySdrOutputReport()->getGainSettings()->back()->setName(new QString(itGain.m_name.c_str()));
1698  }
1699  }
1700 
1701  if (channelSettings->m_frequencySettings.size() != 0)
1702  {
1703  response.getSoapySdrOutputReport()->setFrequencySettings(new QList<SWGSDRangel::SWGSoapySDRFrequencySetting*>);
1704 
1705  for (const auto itFreq : channelSettings->m_frequencySettings)
1706  {
1708  response.getSoapySdrOutputReport()->getFrequencySettings()->back()->setRanges(new QList<SWGSDRangel::SWGRangeFloat*>);
1709 
1710  for (const auto itRange : itFreq.m_ranges)
1711  {
1712  response.getSoapySdrOutputReport()->getFrequencySettings()->back()->getRanges()->append(new SWGSDRangel::SWGRangeFloat());
1713  response.getSoapySdrOutputReport()->getFrequencySettings()->back()->getRanges()->back()->setMin(itRange.minimum());
1714  response.getSoapySdrOutputReport()->getFrequencySettings()->back()->getRanges()->back()->setMax(itRange.maximum());
1715  }
1716 
1717  response.getSoapySdrOutputReport()->getFrequencySettings()->back()->setName(new QString(itFreq.m_name.c_str()));
1718  }
1719  }
1720 
1721  if (channelSettings->m_ratesRanges.size() != 0)
1722  {
1723  response.getSoapySdrOutputReport()->setRatesRanges(new QList<SWGSDRangel::SWGRangeFloat*>);
1724 
1725  for (const auto itRange : channelSettings->m_ratesRanges)
1726  {
1728  response.getSoapySdrOutputReport()->getRatesRanges()->back()->setMin(itRange.minimum());
1729  response.getSoapySdrOutputReport()->getRatesRanges()->back()->setMax(itRange.maximum());
1730  }
1731  }
1732 
1733  if (channelSettings->m_bandwidthsRanges.size() != 0)
1734  {
1735  response.getSoapySdrOutputReport()->setBandwidthsRanges(new QList<SWGSDRangel::SWGRangeFloat*>);
1736 
1737  for (const auto itBandwidth : channelSettings->m_bandwidthsRanges)
1738  {
1740  response.getSoapySdrOutputReport()->getBandwidthsRanges()->back()->setMin(itBandwidth.minimum());
1741  response.getSoapySdrOutputReport()->getBandwidthsRanges()->back()->setMax(itBandwidth.maximum());
1742  }
1743  }
1744 }
void setHasFrequencyCorrectionValue(qint32 has_frequency_correction_value)
int m_channel
allocated channel (-1 if none)
void setFrequencySettingsArgs(QList< SWGArgInfo *> *frequency_settings_args)
SoapySDR::ArgInfoList m_frequencySettingsArgs
common tuning parameters
bool m_hasFrequencyCorrectionValue
Frequency correction value flag.
QList< SWGSoapySDRGainSetting * > * getGainSettings()
bool m_hasDCOffsetValue
DC offset value flag.
void setDeviceSettingsArgs(QList< SWGArgInfo *> *device_settings_args)
bool m_hasDCAutoCorrection
DC offset auto correction flag.
QList< SWGArgInfo * > * getStreamSettingsArgs()
void setStreamSettingsArgs(QList< SWGArgInfo *> *stream_settings_args)
std::vector< FrequencySetting > m_frequencySettings
tunable elements settings
void setGainRange(SWGRangeFloat *gain_range)
void setHasDcAutoCorrection(qint32 has_dc_auto_correction)
QList< SWGArgInfo * > * getDeviceSettingsArgs()
void setRatesRanges(QList< SWGRangeFloat *> *rates_ranges)
void setGainSettings(QList< SWGSoapySDRGainSetting *> *gain_settings)
std::vector< std::string > m_antennas
Antenna ports names.
DeviceSoapySDRParams * m_deviceParams
SoapySDR::RangeList m_ratesRanges
list of ranges of sample rates
void setBandwidthsRanges(QList< SWGRangeFloat *> *bandwidths_ranges)
const SoapySDR::ArgInfoList & getDeviceArgs() const
QList< SWGArgInfo * > * getFrequencySettingsArgs()
SWGSoapySDRReport * getSoapySdrOutputReport()
QList< SWGRangeFloat * > * getBandwidthsRanges()
void webapiFormatArgInfo(const SoapySDR::ArgInfo &arg, SWGSDRangel::SWGArgInfo *argInfo)
SoapySDR::RangeList m_bandwidthsRanges
list of ranges of bandwidths
QList< SWGSoapySDRFrequencySetting * > * getFrequencySettings()
void setFrequencySettings(QList< SWGSoapySDRFrequencySetting *> *frequency_settings)
const ChannelSettings * getTxChannelSettings(uint32_t index)
void setHasIqBalanceValue(qint32 has_iq_balance_value)
std::vector< GainSetting > m_gainSettings
gain elements settings
DeviceSoapySDRShared m_deviceShared
QList< QString * > * getAntennas()
SoapySDR::ArgInfoList m_streamSettingsArgs
common stream parameters
QList< SWGRangeFloat * > * getRatesRanges()
bool m_hasIQBalanceValue
IQ correction value flag.
void setAntennas(QList< QString *> *antennas)
void setHasDcOffsetValue(qint32 has_dc_offset_value)
SoapySDR::Range m_gainRange
Global gain range.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiFormatDeviceSettings()

void SoapySDROutput::webapiFormatDeviceSettings ( SWGSDRangel::SWGDeviceSettings response,
const SoapySDROutputSettings settings 
)
private

Definition at line 1531 of file soapysdroutput.cpp.

References arg(), SWGSDRangel::SWGSoapySDROutputSettings::getAntenna(), SWGSDRangel::SWGSoapySDROutputSettings::getDcCorrection(), SWGSDRangel::SWGSoapySDROutputSettings::getDeviceArgSettings(), SWGSDRangel::SWGSoapySDROutputSettings::getIndividualGains(), SWGSDRangel::SWGSoapySDROutputSettings::getIqCorrection(), SWGSDRangel::SWGSoapySDROutputSettings::getReverseApiAddress(), SWGSDRangel::SWGDeviceSettings::getSoapySdrOutputSettings(), SWGSDRangel::SWGSoapySDROutputSettings::getStreamArgSettings(), SWGSDRangel::SWGSoapySDROutputSettings::getTunableElements(), SoapySDROutputSettings::m_antenna, SoapySDROutputSettings::m_autoDCCorrection, SoapySDROutputSettings::m_autoGain, SoapySDROutputSettings::m_autoIQCorrection, SoapySDROutputSettings::m_bandwidth, SoapySDROutputSettings::m_centerFrequency, SoapySDROutputSettings::m_dcCorrection, SoapySDROutputSettings::m_deviceArgSettings, SoapySDROutputSettings::m_devSampleRate, SoapySDROutputSettings::m_globalGain, SoapySDROutputSettings::m_individualGains, SoapySDROutputSettings::m_iqCorrection, SoapySDROutputSettings::m_log2Interp, SoapySDROutputSettings::m_LOppmTenths, SoapySDROutputSettings::m_reverseAPIAddress, SoapySDROutputSettings::m_reverseAPIDeviceIndex, SoapySDROutputSettings::m_reverseAPIPort, SoapySDROutputSettings::m_streamArgSettings, SoapySDROutputSettings::m_transverterDeltaFrequency, SoapySDROutputSettings::m_transverterMode, SoapySDROutputSettings::m_tunableElements, SoapySDROutputSettings::m_useReverseAPI, SWGSDRangel::SWGSoapySDROutputSettings::setAntenna(), SWGSDRangel::SWGSoapySDROutputSettings::setAutoDcCorrection(), SWGSDRangel::SWGSoapySDROutputSettings::setAutoGain(), SWGSDRangel::SWGSoapySDROutputSettings::setAutoIqCorrection(), SWGSDRangel::SWGSoapySDROutputSettings::setBandwidth(), SWGSDRangel::SWGSoapySDROutputSettings::setCenterFrequency(), SWGSDRangel::SWGSoapySDROutputSettings::setDcCorrection(), SWGSDRangel::SWGSoapySDROutputSettings::setDeviceArgSettings(), SWGSDRangel::SWGSoapySDROutputSettings::setDevSampleRate(), SWGSDRangel::SWGSoapySDROutputSettings::setGlobalGain(), SWGSDRangel::SWGComplex::setImag(), SWGSDRangel::SWGSoapySDROutputSettings::setIndividualGains(), SWGSDRangel::SWGSoapySDROutputSettings::setIqCorrection(), SWGSDRangel::SWGSoapySDROutputSettings::setLog2Interp(), SWGSDRangel::SWGSoapySDROutputSettings::setLOppmTenths(), SWGSDRangel::SWGComplex::setReal(), SWGSDRangel::SWGSoapySDROutputSettings::setReverseApiAddress(), SWGSDRangel::SWGSoapySDROutputSettings::setReverseApiDeviceIndex(), SWGSDRangel::SWGSoapySDROutputSettings::setReverseApiPort(), SWGSDRangel::SWGSoapySDROutputSettings::setStreamArgSettings(), SWGSDRangel::SWGSoapySDROutputSettings::setTransverterDeltaFrequency(), SWGSDRangel::SWGSoapySDROutputSettings::setTransverterMode(), SWGSDRangel::SWGSoapySDROutputSettings::setTunableElements(), SWGSDRangel::SWGSoapySDROutputSettings::setUseReverseApi(), and webapiFormatArgValue().

Referenced by webapiSettingsGet(), and webapiSettingsPutPatch().

1532 {
1538  response.getSoapySdrOutputSettings()->setTransverterMode(settings.m_transverterMode ? 1 : 0);
1539 
1540  if (response.getSoapySdrOutputSettings()->getAntenna()) {
1541  *response.getSoapySdrOutputSettings()->getAntenna() = settings.m_antenna;
1542  } else {
1543  response.getSoapySdrOutputSettings()->setAntenna(new QString(settings.m_antenna));
1544  }
1545 
1546  if (response.getSoapySdrOutputSettings()->getTunableElements()) {
1547  response.getSoapySdrOutputSettings()->getTunableElements()->clear();
1548  } else {
1549  response.getSoapySdrOutputSettings()->setTunableElements(new QList<SWGSDRangel::SWGArgValue*>);
1550  }
1551 
1552  for (const auto itName : settings.m_tunableElements.keys())
1553  {
1555  response.getSoapySdrOutputSettings()->getTunableElements()->back()->setKey(new QString( itName));
1556  double value = settings.m_tunableElements.value(itName);
1557  response.getSoapySdrOutputSettings()->getTunableElements()->back()->setValueString(new QString(tr("%1").arg(value)));
1558  response.getSoapySdrOutputSettings()->getTunableElements()->back()->setValueType(new QString("float"));
1559  }
1560 
1561  response.getSoapySdrOutputSettings()->setBandwidth(settings.m_bandwidth);
1563 
1564  if (response.getSoapySdrOutputSettings()->getIndividualGains()) {
1565  response.getSoapySdrOutputSettings()->getIndividualGains()->clear();
1566  } else {
1567  response.getSoapySdrOutputSettings()->setIndividualGains(new QList<SWGSDRangel::SWGArgValue*>);
1568  }
1569 
1570  for (const auto itName : settings.m_individualGains.keys())
1571  {
1573  response.getSoapySdrOutputSettings()->getIndividualGains()->back()->setKey(new QString(itName));
1574  double value = settings.m_individualGains.value(itName);
1575  response.getSoapySdrOutputSettings()->getIndividualGains()->back()->setValueString(new QString(tr("%1").arg(value)));
1576  response.getSoapySdrOutputSettings()->getIndividualGains()->back()->setValueType(new QString("float"));
1577  }
1578 
1579  response.getSoapySdrOutputSettings()->setAutoGain(settings.m_autoGain ? 1 : 0);
1582 
1583  if (!response.getSoapySdrOutputSettings()->getDcCorrection()) {
1585  }
1586 
1587  response.getSoapySdrOutputSettings()->getDcCorrection()->setReal(settings.m_dcCorrection.real());
1588  response.getSoapySdrOutputSettings()->getDcCorrection()->setImag(settings.m_dcCorrection.imag());
1589 
1590  if (!response.getSoapySdrOutputSettings()->getIqCorrection()) {
1592  }
1593 
1594  response.getSoapySdrOutputSettings()->getIqCorrection()->setReal(settings.m_iqCorrection.real());
1595  response.getSoapySdrOutputSettings()->getIqCorrection()->setImag(settings.m_iqCorrection.imag());
1596 
1597  if (response.getSoapySdrOutputSettings()->getStreamArgSettings()) {
1598  response.getSoapySdrOutputSettings()->getStreamArgSettings()->clear();
1599  } else {
1600  response.getSoapySdrOutputSettings()->setStreamArgSettings(new QList<SWGSDRangel::SWGArgValue*>);
1601  }
1602 
1603  for (const auto itName : settings.m_streamArgSettings.keys())
1604  {
1606  response.getSoapySdrOutputSettings()->getStreamArgSettings()->back()->setKey(new QString(itName));
1607  const QVariant& v = settings.m_streamArgSettings.value(itName);
1609  }
1610 
1611  if (response.getSoapySdrOutputSettings()->getDeviceArgSettings()) {
1612  response.getSoapySdrOutputSettings()->getDeviceArgSettings()->clear();
1613  } else {
1614  response.getSoapySdrOutputSettings()->setDeviceArgSettings(new QList<SWGSDRangel::SWGArgValue*>);
1615  }
1616 
1617  for (const auto itName : settings.m_deviceArgSettings.keys())
1618  {
1620  response.getSoapySdrOutputSettings()->getDeviceArgSettings()->back()->setKey(new QString(itName));
1621  const QVariant& v = settings.m_deviceArgSettings.value(itName);
1623  }
1624 
1625  response.getSoapySdrOutputSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
1626 
1627  if (response.getSoapySdrOutputSettings()->getReverseApiAddress()) {
1629  } else {
1630  response.getSoapySdrOutputSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress));
1631  }
1632 
1635 }
void setAutoIqCorrection(qint32 auto_iq_correction)
QMap< QString, double > m_tunableElements
void setAutoDcCorrection(qint32 auto_dc_correction)
void setReal(float real)
Definition: SWGComplex.cpp:101
void setTunableElements(QList< SWGArgValue *> *tunable_elements)
SWGSoapySDROutputSettings * getSoapySdrOutputSettings()
void setIndividualGains(QList< SWGArgValue *> *individual_gains)
QMap< QString, QVariant > m_streamArgSettings
void setImag(float imag)
Definition: SWGComplex.cpp:111
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
void setIqCorrection(SWGComplex *iq_correction)
QMap< QString, double > m_individualGains
void setDcCorrection(SWGComplex *dc_correction)
std::complex< double > m_iqCorrection
void setReverseApiDeviceIndex(qint32 reverse_api_device_index)
void setReverseApiAddress(QString *reverse_api_address)
void setTransverterDeltaFrequency(qint64 transverter_delta_frequency)
void setDeviceArgSettings(QList< SWGArgValue *> *device_arg_settings)
std::complex< double > m_dcCorrection
void setStreamArgSettings(QList< SWGArgValue *> *stream_arg_settings)
void webapiFormatArgValue(const QVariant &v, SWGSDRangel::SWGArgValue *argValue)
QMap< QString, QVariant > m_deviceArgSettings
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiReportGet()

int SoapySDROutput::webapiReportGet ( SWGSDRangel::SWGDeviceReport response,
QString &  errorMessage 
)
virtual

Reimplemented from DeviceSampleSink.

Definition at line 1494 of file soapysdroutput.cpp.

References SWGSDRangel::SWGDeviceReport::getSoapySdrOutputReport(), SWGSDRangel::SWGSoapySDRReport::init(), SWGSDRangel::SWGDeviceReport::setSoapySdrOutputReport(), and webapiFormatDeviceReport().

1495 {
1496  (void) errorMessage;
1498  response.getSoapySdrOutputReport()->init();
1499  webapiFormatDeviceReport(response);
1500  return 200;
1501 }
void setSoapySdrOutputReport(SWGSoapySDRReport *soapy_sdr_output_report)
SWGSoapySDRReport * getSoapySdrOutputReport()
void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport &response)
+ Here is the call graph for this function:

◆ webapiReverseSendSettings()

void SoapySDROutput::webapiReverseSendSettings ( QList< QString > &  deviceSettingsKeys,
const SoapySDROutputSettings settings,
bool  force 
)
private

Definition at line 1822 of file soapysdroutput.cpp.

References SWGSDRangel::SWGDeviceSettings::asJson(), SWGSDRangel::SWGSoapySDROutputSettings::getDcCorrection(), DeviceAPI::getDeviceSetIndex(), SWGSDRangel::SWGSoapySDROutputSettings::getIqCorrection(), SWGSDRangel::SWGDeviceSettings::getSoapySdrOutputSettings(), SWGSDRangel::SWGSoapySDROutputSettings::init(), SoapySDROutputSettings::m_antenna, SoapySDROutputSettings::m_autoDCCorrection, SoapySDROutputSettings::m_autoGain, SoapySDROutputSettings::m_autoIQCorrection, SoapySDROutputSettings::m_bandwidth, SoapySDROutputSettings::m_centerFrequency, SoapySDROutputSettings::m_dcCorrection, m_deviceAPI, SoapySDROutputSettings::m_devSampleRate, SoapySDROutputSettings::m_globalGain, SoapySDROutputSettings::m_iqCorrection, SoapySDROutputSettings::m_log2Interp, SoapySDROutputSettings::m_LOppmTenths, m_networkManager, m_networkRequest, SoapySDROutputSettings::m_reverseAPIAddress, SoapySDROutputSettings::m_reverseAPIDeviceIndex, SoapySDROutputSettings::m_reverseAPIPort, SoapySDROutputSettings::m_transverterDeltaFrequency, SoapySDROutputSettings::m_transverterMode, SWGSDRangel::SWGSoapySDROutputSettings::setAntenna(), SWGSDRangel::SWGSoapySDROutputSettings::setAutoDcCorrection(), SWGSDRangel::SWGSoapySDROutputSettings::setAutoGain(), SWGSDRangel::SWGSoapySDROutputSettings::setAutoIqCorrection(), SWGSDRangel::SWGSoapySDROutputSettings::setBandwidth(), SWGSDRangel::SWGSoapySDROutputSettings::setCenterFrequency(), SWGSDRangel::SWGSoapySDROutputSettings::setDcCorrection(), SWGSDRangel::SWGDeviceSettings::setDeviceHwType(), SWGSDRangel::SWGSoapySDROutputSettings::setDevSampleRate(), SWGSDRangel::SWGDeviceSettings::setDirection(), SWGSDRangel::SWGSoapySDROutputSettings::setGlobalGain(), SWGSDRangel::SWGComplex::setImag(), SWGSDRangel::SWGSoapySDROutputSettings::setIqCorrection(), SWGSDRangel::SWGSoapySDROutputSettings::setLog2Interp(), SWGSDRangel::SWGSoapySDROutputSettings::setLOppmTenths(), SWGSDRangel::SWGDeviceSettings::setOriginatorIndex(), SWGSDRangel::SWGComplex::setReal(), SWGSDRangel::SWGDeviceSettings::setSoapySdrOutputSettings(), SWGSDRangel::SWGSoapySDROutputSettings::setTransverterDeltaFrequency(), and SWGSDRangel::SWGSoapySDROutputSettings::setTransverterMode().

Referenced by applySettings().

1823 {
1825  swgDeviceSettings->setDirection(1); // Single Tx
1826  swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
1827  swgDeviceSettings->setDeviceHwType(new QString("SoapySDR"));
1829  swgDeviceSettings->getSoapySdrOutputSettings()->init();
1830  SWGSDRangel::SWGSoapySDROutputSettings *swgSoapySDROutputSettings = swgDeviceSettings->getSoapySdrOutputSettings();
1831 
1832  // transfer data that has been modified. When force is on transfer all data except reverse API data
1833 
1834  if (deviceSettingsKeys.contains("centerFrequency") || force) {
1835  swgSoapySDROutputSettings->setCenterFrequency(settings.m_centerFrequency);
1836  }
1837  if (deviceSettingsKeys.contains("LOppmTenths") || force) {
1838  swgSoapySDROutputSettings->setLOppmTenths(settings.m_LOppmTenths);
1839  }
1840  if (deviceSettingsKeys.contains("devSampleRate") || force) {
1841  swgSoapySDROutputSettings->setDevSampleRate(settings.m_devSampleRate);
1842  }
1843  if (deviceSettingsKeys.contains("bandwidth") || force) {
1844  swgSoapySDROutputSettings->setBandwidth(settings.m_bandwidth);
1845  }
1846  if (deviceSettingsKeys.contains("log2Interp") || force) {
1847  swgSoapySDROutputSettings->setLog2Interp(settings.m_log2Interp);
1848  }
1849  if (deviceSettingsKeys.contains("transverterDeltaFrequency") || force) {
1850  swgSoapySDROutputSettings->setTransverterDeltaFrequency(settings.m_transverterDeltaFrequency);
1851  }
1852  if (deviceSettingsKeys.contains("transverterMode") || force) {
1853  swgSoapySDROutputSettings->setTransverterMode(settings.m_transverterMode ? 1 : 0);
1854  }
1855  if (deviceSettingsKeys.contains("antenna") || force) {
1856  swgSoapySDROutputSettings->setAntenna(new QString(settings.m_antenna));
1857  }
1858  if (deviceSettingsKeys.contains("globalGain") || force) {
1859  swgSoapySDROutputSettings->setGlobalGain(settings.m_globalGain);
1860  }
1861  if (deviceSettingsKeys.contains("autoGain") || force) {
1862  swgSoapySDROutputSettings->setAutoGain(settings.m_autoGain ? 1 : 0);
1863  }
1864  if (deviceSettingsKeys.contains("autoDCCorrection") || force) {
1865  swgSoapySDROutputSettings->setAutoDcCorrection(settings.m_autoDCCorrection ? 1 : 0);
1866  }
1867  if (deviceSettingsKeys.contains("autoIQCorrection") || force) {
1868  swgSoapySDROutputSettings->setAutoIqCorrection(settings.m_autoIQCorrection ? 1 : 0);
1869  }
1870  if (deviceSettingsKeys.contains("dcCorrection") || force)
1871  {
1872  swgSoapySDROutputSettings->setDcCorrection(new SWGSDRangel::SWGComplex());
1873  swgSoapySDROutputSettings->getDcCorrection()->setReal(settings.m_dcCorrection.real());
1874  swgSoapySDROutputSettings->getDcCorrection()->setImag(settings.m_dcCorrection.imag());
1875  }
1876  if (deviceSettingsKeys.contains("iqCorrection") || force)
1877  {
1878  swgSoapySDROutputSettings->setIqCorrection(new SWGSDRangel::SWGComplex());
1879  swgSoapySDROutputSettings->getIqCorrection()->setReal(settings.m_iqCorrection.real());
1880  swgSoapySDROutputSettings->getIqCorrection()->setImag(settings.m_iqCorrection.imag());
1881  }
1882 
1883  QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings")
1884  .arg(settings.m_reverseAPIAddress)
1885  .arg(settings.m_reverseAPIPort)
1886  .arg(settings.m_reverseAPIDeviceIndex);
1887  m_networkRequest.setUrl(QUrl(deviceSettingsURL));
1888  m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
1889 
1890  QBuffer *buffer=new QBuffer();
1891  buffer->open((QBuffer::ReadWrite));
1892  buffer->write(swgDeviceSettings->asJson().toUtf8());
1893  buffer->seek(0);
1894 
1895  // Always use PATCH to avoid passing reverse API settings
1896  m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer);
1897 
1898  delete swgDeviceSettings;
1899 }
void setAutoIqCorrection(qint32 auto_iq_correction)
void setAutoDcCorrection(qint32 auto_dc_correction)
void setReal(float real)
Definition: SWGComplex.cpp:101
virtual QString asJson() override
void setSoapySdrOutputSettings(SWGSoapySDROutputSettings *soapy_sdr_output_settings)
QNetworkRequest m_networkRequest
SWGSoapySDROutputSettings * getSoapySdrOutputSettings()
void setOriginatorIndex(qint32 originator_index)
void setImag(float imag)
Definition: SWGComplex.cpp:111
void setIqCorrection(SWGComplex *iq_correction)
int getDeviceSetIndex() const
Definition: deviceapi.h:131
void setDcCorrection(SWGComplex *dc_correction)
std::complex< double > m_iqCorrection
void setTransverterDeltaFrequency(qint64 transverter_delta_frequency)
std::complex< double > m_dcCorrection
DeviceAPI * m_deviceAPI
void setDirection(qint32 direction)
QNetworkAccessManager * m_networkManager
void setDeviceHwType(QString *device_hw_type)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiReverseSendStartStop()

void SoapySDROutput::webapiReverseSendStartStop ( bool  start)
private

Definition at line 1901 of file soapysdroutput.cpp.

References SWGSDRangel::SWGDeviceSettings::asJson(), DeviceAPI::getDeviceSetIndex(), m_deviceAPI, m_networkManager, m_networkRequest, SoapySDROutputSettings::m_reverseAPIAddress, SoapySDROutputSettings::m_reverseAPIDeviceIndex, SoapySDROutputSettings::m_reverseAPIPort, m_settings, SWGSDRangel::SWGDeviceSettings::setDeviceHwType(), SWGSDRangel::SWGDeviceSettings::setDirection(), and SWGSDRangel::SWGDeviceSettings::setOriginatorIndex().

Referenced by handleMessage().

1902 {
1904  swgDeviceSettings->setDirection(1); // Single Tx
1905  swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
1906  swgDeviceSettings->setDeviceHwType(new QString("SoapySDR"));
1907 
1908  QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/run")
1912  m_networkRequest.setUrl(QUrl(deviceSettingsURL));
1913  m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
1914 
1915  QBuffer *buffer=new QBuffer();
1916  buffer->open((QBuffer::ReadWrite));
1917  buffer->write(swgDeviceSettings->asJson().toUtf8());
1918  buffer->seek(0);
1919 
1920  if (start) {
1921  m_networkManager->sendCustomRequest(m_networkRequest, "POST", buffer);
1922  } else {
1923  m_networkManager->sendCustomRequest(m_networkRequest, "DELETE", buffer);
1924  }
1925 
1926  delete swgDeviceSettings;
1927 }
virtual QString asJson() override
QNetworkRequest m_networkRequest
void setOriginatorIndex(qint32 originator_index)
virtual bool start()
int getDeviceSetIndex() const
Definition: deviceapi.h:131
SoapySDROutputSettings m_settings
DeviceAPI * m_deviceAPI
void setDirection(qint32 direction)
QNetworkAccessManager * m_networkManager
void setDeviceHwType(QString *device_hw_type)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ webapiRun()

int SoapySDROutput::webapiRun ( bool  run,
SWGSDRangel::SWGDeviceState response,
QString &  errorMessage 
)
virtual

Reimplemented from DeviceSampleSink.

Definition at line 1512 of file soapysdroutput.cpp.

References SoapySDROutput::MsgStartStop::create(), DeviceAPI::getDeviceEngineStateStr(), SWGSDRangel::SWGDeviceState::getState(), m_deviceAPI, DeviceSampleSink::m_guiMessageQueue, DeviceSampleSink::m_inputMessageQueue, and MessageQueue::push().

1516 {
1517  (void) errorMessage;
1519  MsgStartStop *message = MsgStartStop::create(run);
1520  m_inputMessageQueue.push(message);
1521 
1522  if (m_guiMessageQueue) // forward to GUI if any
1523  {
1524  MsgStartStop *msgToGUI = MsgStartStop::create(run);
1525  m_guiMessageQueue->push(msgToGUI);
1526  }
1527 
1528  return 200;
1529 }
void push(Message *message, bool emitSignal=true)
Push message onto queue.
MessageQueue m_inputMessageQueue
Input queue to the sink.
void getDeviceEngineStateStr(QString &state)
Definition: deviceapi.cpp:389
static MsgStartStop * create(bool startStop)
DeviceAPI * m_deviceAPI
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
+ Here is the call graph for this function:

◆ webapiRunGet()

int SoapySDROutput::webapiRunGet ( SWGSDRangel::SWGDeviceState response,
QString &  errorMessage 
)
virtual

Reimplemented from DeviceSampleSink.

Definition at line 1503 of file soapysdroutput.cpp.

References DeviceAPI::getDeviceEngineStateStr(), SWGSDRangel::SWGDeviceState::getState(), and m_deviceAPI.

1506 {
1507  (void) errorMessage;
1509  return 200;
1510 }
void getDeviceEngineStateStr(QString &state)
Definition: deviceapi.cpp:389
DeviceAPI * m_deviceAPI
+ Here is the call graph for this function:

◆ webapiSettingsGet()

int SoapySDROutput::webapiSettingsGet ( SWGSDRangel::SWGDeviceSettings response,
QString &  errorMessage 
)
virtual

Reimplemented from DeviceSampleSink.

Definition at line 1339 of file soapysdroutput.cpp.

References SWGSDRangel::SWGDeviceSettings::getSoapySdrOutputSettings(), SWGSDRangel::SWGSoapySDROutputSettings::init(), m_settings, SWGSDRangel::SWGDeviceSettings::setSoapySdrOutputSettings(), and webapiFormatDeviceSettings().

1342 {
1343  (void) errorMessage;
1345  response.getSoapySdrOutputSettings()->init();
1347  return 200;
1348 }
void setSoapySdrOutputSettings(SWGSoapySDROutputSettings *soapy_sdr_output_settings)
SWGSoapySDROutputSettings * getSoapySdrOutputSettings()
void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings &response, const SoapySDROutputSettings &settings)
SoapySDROutputSettings m_settings
+ Here is the call graph for this function:

◆ webapiSettingsPutPatch()

int SoapySDROutput::webapiSettingsPutPatch ( bool  force,
const QStringList &  deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings response,
QString &  errorMessage 
)
virtual

Reimplemented from DeviceSampleSink.

Definition at line 1350 of file soapysdroutput.cpp.

References SoapySDROutput::MsgConfigureSoapySDROutput::create(), SWGSDRangel::SWGSoapySDROutputSettings::getAntenna(), SWGSDRangel::SWGSoapySDROutputSettings::getAutoDcCorrection(), SWGSDRangel::SWGSoapySDROutputSettings::getAutoGain(), SWGSDRangel::SWGSoapySDROutputSettings::getAutoIqCorrection(), SWGSDRangel::SWGSoapySDROutputSettings::getBandwidth(), SWGSDRangel::SWGSoapySDROutputSettings::getCenterFrequency(), SWGSDRangel::SWGSoapySDROutputSettings::getDcCorrection(), SWGSDRangel::SWGSoapySDROutputSettings::getDeviceArgSettings(), SWGSDRangel::SWGSoapySDROutputSettings::getDevSampleRate(), SWGSDRangel::SWGSoapySDROutputSettings::getGlobalGain(), SWGSDRangel::SWGComplex::getImag(), SWGSDRangel::SWGSoapySDROutputSettings::getIndividualGains(), SWGSDRangel::SWGSoapySDROutputSettings::getIqCorrection(), SWGSDRangel::SWGSoapySDROutputSettings::getLog2Interp(), SWGSDRangel::SWGSoapySDROutputSettings::getLOppmTenths(), SWGSDRangel::SWGComplex::getReal(), SWGSDRangel::SWGSoapySDROutputSettings::getReverseApiAddress(), SWGSDRangel::SWGSoapySDROutputSettings::getReverseApiDeviceIndex(), SWGSDRangel::SWGSoapySDROutputSettings::getReverseApiPort(), SWGSDRangel::SWGDeviceSettings::getSoapySdrOutputSettings(), SWGSDRangel::SWGSoapySDROutputSettings::getStreamArgSettings(), SWGSDRangel::SWGSoapySDROutputSettings::getTransverterDeltaFrequency(), SWGSDRangel::SWGSoapySDROutputSettings::getTransverterMode(), SWGSDRangel::SWGSoapySDROutputSettings::getTunableElements(), SWGSDRangel::SWGSoapySDROutputSettings::getUseReverseApi(), SoapySDROutputSettings::m_antenna, SoapySDROutputSettings::m_autoDCCorrection, SoapySDROutputSettings::m_autoGain, SoapySDROutputSettings::m_autoIQCorrection, SoapySDROutputSettings::m_bandwidth, SoapySDROutputSettings::m_centerFrequency, SoapySDROutputSettings::m_dcCorrection, SoapySDROutputSettings::m_deviceArgSettings, SoapySDROutputSettings::m_devSampleRate, SoapySDROutputSettings::m_globalGain, DeviceSampleSink::m_guiMessageQueue, SoapySDROutputSettings::m_individualGains, DeviceSampleSink::m_inputMessageQueue, SoapySDROutputSettings::m_iqCorrection, SoapySDROutputSettings::m_log2Interp, SoapySDROutputSettings::m_LOppmTenths, SoapySDROutputSettings::m_reverseAPIAddress, SoapySDROutputSettings::m_reverseAPIDeviceIndex, SoapySDROutputSettings::m_reverseAPIPort, m_settings, SoapySDROutputSettings::m_streamArgSettings, SoapySDROutputSettings::m_transverterDeltaFrequency, SoapySDROutputSettings::m_transverterMode, SoapySDROutputSettings::m_tunableElements, SoapySDROutputSettings::m_useReverseAPI, MessageQueue::push(), webapiFormatDeviceSettings(), and webapiVariantFromArgValue().

1355 {
1356  (void) errorMessage;
1358 
1359  if (deviceSettingsKeys.contains("centerFrequency")) {
1361  }
1362  if (deviceSettingsKeys.contains("LOppmTenths")) {
1363  settings.m_LOppmTenths = response.getSoapySdrOutputSettings()->getLOppmTenths();
1364  }
1365  if (deviceSettingsKeys.contains("devSampleRate")) {
1367  }
1368  if (deviceSettingsKeys.contains("bandwidth")) {
1369  settings.m_bandwidth = response.getSoapySdrOutputSettings()->getBandwidth();
1370  }
1371  if (deviceSettingsKeys.contains("log2Interp")) {
1372  settings.m_log2Interp = response.getSoapySdrOutputSettings()->getLog2Interp();
1373  }
1374  if (deviceSettingsKeys.contains("transverterDeltaFrequency")) {
1376  }
1377  if (deviceSettingsKeys.contains("transverterMode")) {
1378  settings.m_transverterMode = response.getSoapySdrOutputSettings()->getTransverterMode() != 0;
1379  }
1380  if (deviceSettingsKeys.contains("antenna")) {
1381  settings.m_antenna = *response.getSoapySdrOutputSettings()->getAntenna();
1382  }
1383 
1384  if (deviceSettingsKeys.contains("tunableElements"))
1385  {
1386  QList<SWGSDRangel::SWGArgValue*> *tunableElements = response.getSoapySdrOutputSettings()->getTunableElements();
1387 
1388  for (const auto &itArg : *tunableElements)
1389  {
1390  QMap<QString, double>::iterator itSettings = settings.m_tunableElements.find(*(itArg->getKey()));
1391 
1392  if (itSettings != settings.m_tunableElements.end())
1393  {
1394  QVariant v = webapiVariantFromArgValue(itArg);
1395  itSettings.value() = v.toDouble();
1396  }
1397  }
1398  }
1399 
1400  if (deviceSettingsKeys.contains("globalGain")) {
1401  settings.m_globalGain = response.getSoapySdrOutputSettings()->getGlobalGain();
1402  }
1403 
1404  if (deviceSettingsKeys.contains("individualGains"))
1405  {
1406  QList<SWGSDRangel::SWGArgValue*> *individualGains = response.getSoapySdrOutputSettings()->getIndividualGains();
1407 
1408  for (const auto &itArg : *individualGains)
1409  {
1410  QMap<QString, double>::iterator itSettings = settings.m_individualGains.find(*(itArg->getKey()));
1411 
1412  if (itSettings != settings.m_individualGains.end())
1413  {
1414  QVariant v = webapiVariantFromArgValue(itArg);
1415  itSettings.value() = v.toDouble();
1416  }
1417  }
1418  }
1419 
1420  if (deviceSettingsKeys.contains("autoGain")) {
1421  settings.m_autoGain = response.getSoapySdrOutputSettings()->getAutoGain() != 0;
1422  }
1423  if (deviceSettingsKeys.contains("autoDCCorrection")) {
1425  }
1426  if (deviceSettingsKeys.contains("autoIQCorrection")) {
1428  }
1429  if (deviceSettingsKeys.contains("dcCorrection"))
1430  {
1431  settings.m_dcCorrection.real(response.getSoapySdrOutputSettings()->getDcCorrection()->getReal());
1432  settings.m_dcCorrection.imag(response.getSoapySdrOutputSettings()->getDcCorrection()->getImag());
1433  }
1434  if (deviceSettingsKeys.contains("iqCorrection"))
1435  {
1436  settings.m_iqCorrection.real(response.getSoapySdrOutputSettings()->getIqCorrection()->getReal());
1437  settings.m_iqCorrection.imag(response.getSoapySdrOutputSettings()->getIqCorrection()->getImag());
1438  }
1439 
1440  if (deviceSettingsKeys.contains("streamArgSettings"))
1441  {
1442  QList<SWGSDRangel::SWGArgValue*> *streamArgSettings = response.getSoapySdrOutputSettings()->getStreamArgSettings();
1443 
1444  for (const auto itArg : *streamArgSettings)
1445  {
1446  QMap<QString, QVariant>::iterator itSettings = settings.m_streamArgSettings.find(*itArg->getKey());
1447 
1448  if (itSettings != settings.m_streamArgSettings.end()) {
1449  itSettings.value() = webapiVariantFromArgValue(itArg);
1450  }
1451  }
1452  }
1453 
1454  if (deviceSettingsKeys.contains("deviceArgSettings"))
1455  {
1456  QList<SWGSDRangel::SWGArgValue*> *deviceArgSettings = response.getSoapySdrOutputSettings()->getDeviceArgSettings();
1457 
1458  for (const auto itArg : *deviceArgSettings)
1459  {
1460  QMap<QString, QVariant>::iterator itSettings = settings.m_deviceArgSettings.find(*itArg->getKey());
1461 
1462  if (itSettings != settings.m_deviceArgSettings.end()) {
1463  itSettings.value() = webapiVariantFromArgValue(itArg);
1464  }
1465  }
1466  }
1467 
1468  if (deviceSettingsKeys.contains("useReverseAPI")) {
1469  settings.m_useReverseAPI = response.getSoapySdrOutputSettings()->getUseReverseApi() != 0;
1470  }
1471  if (deviceSettingsKeys.contains("reverseAPIAddress")) {
1473  }
1474  if (deviceSettingsKeys.contains("reverseAPIPort")) {
1476  }
1477  if (deviceSettingsKeys.contains("reverseAPIDeviceIndex")) {
1479  }
1480 
1481  MsgConfigureSoapySDROutput *msg = MsgConfigureSoapySDROutput::create(settings, force);
1483 
1484  if (m_guiMessageQueue) // forward to GUI if any
1485  {
1486  MsgConfigureSoapySDROutput *msgToGUI = MsgConfigureSoapySDROutput::create(settings, force);
1487  m_guiMessageQueue->push(msgToGUI);
1488  }
1489 
1490  webapiFormatDeviceSettings(response, settings);
1491  return 200;
1492 }
static MsgConfigureSoapySDROutput * create(const SoapySDROutputSettings &settings, bool force)
QMap< QString, double > m_tunableElements
void push(Message *message, bool emitSignal=true)
Push message onto queue.
SWGSoapySDROutputSettings * getSoapySdrOutputSettings()
QMap< QString, QVariant > m_streamArgSettings
void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings &response, const SoapySDROutputSettings &settings)
MessageQueue m_inputMessageQueue
Input queue to the sink.
QVariant webapiVariantFromArgValue(SWGSDRangel::SWGArgValue *argValue)
QMap< QString, double > m_individualGains
std::complex< double > m_iqCorrection
SoapySDROutputSettings m_settings
std::complex< double > m_dcCorrection
MessageQueue * m_guiMessageQueue
Input message queue to the GUI.
QMap< QString, QVariant > m_deviceArgSettings
+ Here is the call graph for this function:

◆ webapiVariantFromArgValue()

QVariant SoapySDROutput::webapiVariantFromArgValue ( SWGSDRangel::SWGArgValue argValue)
private

Definition at line 1746 of file soapysdroutput.cpp.

References SWGSDRangel::SWGArgValue::getValueString(), and SWGSDRangel::SWGArgValue::getValueType().

Referenced by webapiSettingsPutPatch().

1747 {
1748  if (*argValue->getValueType() == "bool") {
1749  return QVariant((bool) (*argValue->getValueString() == "1"));
1750  } else if (*argValue->getValueType() == "int") {
1751  return QVariant((int) (atoi(argValue->getValueString()->toStdString().c_str())));
1752  } else if (*argValue->getValueType() == "float") {
1753  return QVariant((double) (atof(argValue->getValueString()->toStdString().c_str())));
1754  } else {
1755  return QVariant(QString(*argValue->getValueString()));
1756  }
1757 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ m_deviceAPI

DeviceAPI* SoapySDROutput::m_deviceAPI
private

◆ m_deviceDescription

QString SoapySDROutput::m_deviceDescription
private

Definition at line 188 of file soapysdroutput.h.

Referenced by getDeviceDescription().

◆ m_deviceShared

DeviceSoapySDRShared SoapySDROutput::m_deviceShared
private

◆ m_mutex

QMutex SoapySDROutput::m_mutex
private

Definition at line 186 of file soapysdroutput.h.

◆ m_networkManager

QNetworkAccessManager* SoapySDROutput::m_networkManager
private

◆ m_networkRequest

QNetworkRequest SoapySDROutput::m_networkRequest
private

Definition at line 193 of file soapysdroutput.h.

Referenced by webapiReverseSendSettings(), and webapiReverseSendStartStop().

◆ m_running

bool SoapySDROutput::m_running
private

Definition at line 189 of file soapysdroutput.h.

Referenced by closeDevice(), start(), stop(), and ~SoapySDROutput().

◆ m_settings

SoapySDROutputSettings SoapySDROutput::m_settings
private

◆ m_thread

SoapySDROutputThread* SoapySDROutput::m_thread
private

Definition at line 190 of file soapysdroutput.h.

Referenced by closeDevice(), findThread(), moveThreadToBuddy(), start(), and stop().


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