XTRX output

This commit is contained in:
f4exb 2019-01-02 15:35:43 +01:00
parent 93f64eee70
commit 73a32a8cd7
40 changed files with 5321 additions and 129 deletions

View File

@ -33,7 +33,9 @@ DeviceXTRXShared::DeviceXTRXShared() :
m_sink(0),
m_inputRate(0),
m_outputRate(0),
m_masterRate(0)
m_masterRate(0),
m_thread(0),
m_threadWasRunning(false)
{}
DeviceXTRXShared::~DeviceXTRXShared()

View File

@ -129,7 +129,6 @@ public:
public:
virtual void startWork() = 0;
virtual void stopWork() = 0;
virtual void setDeviceSampleRate(int sampleRate) = 0;
virtual bool isRunning() = 0;
};
@ -140,6 +139,8 @@ public:
double m_inputRate;
double m_outputRate;
double m_masterRate;
ThreadInterface *m_thread; //!< holds the thread address if started else 0
bool m_threadWasRunning; //!< flag to know if thread needs to be resumed after suspend
static const float m_sampleFifoLengthInSeconds;
static const int m_sampleFifoMinSize;

View File

@ -33,6 +33,11 @@ if(SOAPYSDR_FOUND)
add_subdirectory(soapysdroutput)
endif()
find_package(LibXTRX)
if(LIBXTRX_FOUND)
add_subdirectory(xtrxoutput)
endif(LIBXTRX_FOUND)
if (BUILD_DEBIAN)
add_subdirectory(bladerf1output)
add_subdirectory(bladerf2output)

View File

@ -0,0 +1,56 @@
project(xtrxoutput)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(xtrxoutput_SOURCES
xtrxoutputgui.cpp
xtrxoutput.cpp
xtrxoutputplugin.cpp
xtrxoutputsettings.cpp
xtrxoutputthread.cpp
)
set(xtrxoutput_HEADERS
xtrxoutputgui.h
xtrxoutput.h
xtrxoutputplugin.h
xtrxoutputsettings.h
xtrxoutputthread.h
)
set(xtrxoutput_FORMS
xtrxoutputgui.ui
)
include_directories(
.
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
${CMAKE_SOURCE_DIR}/devices
${LIBXTRX_INCLUDE_DIRS}
)
add_definitions(${QT_DEFINITIONS})
add_definitions(-DQT_PLUGIN)
add_definitions(-DQT_SHARED)
qt5_wrap_ui(xtrxoutput_FORMS_HEADERS ${xtrxoutput_FORMS})
add_library(outputxtrx SHARED
${xtrxoutput_SOURCES}
${xtrxoutput_HEADERS_MOC}
${xtrxoutput_FORMS_HEADERS}
)
target_link_libraries(outputxtrx
${QT_LIBRARIES}
${LIBXTRX_LIBRARIES}
sdrbase
sdrgui
swagger
xtrxdevice
)
target_link_libraries(outputxtrx Qt5::Core Qt5::Widgets)
install(TARGETS outputxtrx DESTINATION lib/plugins/samplesink)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,234 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef PLUGINS_SAMPLESINK_XTRXOUTPUT_XTRXOUTPUT_H_
#define PLUGINS_SAMPLESINK_XTRXOUTPUT_XTRXOUTPUT_H_
#include <stdint.h>
#include <QString>
#include <QByteArray>
#include <QNetworkRequest>
#include "dsp/devicesamplesink.h"
#include "xtrx/devicextrxshared.h"
#include "xtrxoutputsettings.h"
class QNetworkAccessManager;
class QNetworkReply;
class DeviceSinkAPI;
class XTRXOutputThread;
struct DeviceXTRXParams;
class FileRecord;
class XTRXOutput : public DeviceSampleSink
{
Q_OBJECT
public:
class MsgConfigureXTRX : public Message {
MESSAGE_CLASS_DECLARATION
public:
const XTRXOutputSettings& getSettings() const { return m_settings; }
bool getForce() const { return m_force; }
static MsgConfigureXTRX* create(const XTRXOutputSettings& settings, bool force)
{
return new MsgConfigureXTRX(settings, force);
}
private:
XTRXOutputSettings m_settings;
bool m_force;
MsgConfigureXTRX(const XTRXOutputSettings& settings, bool force) :
Message(),
m_settings(settings),
m_force(force)
{ }
};
class MsgGetStreamInfo : public Message {
MESSAGE_CLASS_DECLARATION
public:
static MsgGetStreamInfo* create()
{
return new MsgGetStreamInfo();
}
private:
MsgGetStreamInfo() :
Message()
{ }
};
class MsgGetDeviceInfo : public Message {
MESSAGE_CLASS_DECLARATION
public:
static MsgGetDeviceInfo* create()
{
return new MsgGetDeviceInfo();
}
private:
MsgGetDeviceInfo() :
Message()
{ }
};
class MsgReportStreamInfo : public Message {
MESSAGE_CLASS_DECLARATION
public:
bool getSuccess() const { return m_success; }
bool getActive() const { return m_active; }
uint32_t getFifoFilledCount() const { return m_fifoFilledCount; }
uint32_t getFifoSize() const { return m_fifoSize; }
static MsgReportStreamInfo* create(
bool success,
bool active,
uint32_t fifoFilledCount,
uint32_t fifoSize
)
{
return new MsgReportStreamInfo(
success,
active,
fifoFilledCount,
fifoSize
);
}
private:
bool m_success;
// everything from lms_stream_status_t
bool m_active; //!< Indicates whether the stream is currently active
uint32_t m_fifoFilledCount; //!< Number of samples in FIFO buffer
uint32_t m_fifoSize; //!< Size of FIFO buffer
MsgReportStreamInfo(
bool success,
bool active,
uint32_t fifoFilledCount,
uint32_t fifoSize
) :
Message(),
m_success(success),
m_active(active),
m_fifoFilledCount(fifoFilledCount),
m_fifoSize(fifoSize)
{ }
};
class MsgStartStop : public Message {
MESSAGE_CLASS_DECLARATION
public:
bool getStartStop() const { return m_startStop; }
static MsgStartStop* create(bool startStop) {
return new MsgStartStop(startStop);
}
protected:
bool m_startStop;
MsgStartStop(bool startStop) :
Message(),
m_startStop(startStop)
{ }
};
XTRXOutput(DeviceSinkAPI *deviceAPI);
virtual ~XTRXOutput();
virtual void destroy();
virtual void init();
virtual bool start();
virtual void stop();
XTRXOutputThread *getThread() { return m_XTRXOutputThread; }
void setThread(XTRXOutputThread *thread) { m_XTRXOutputThread = thread; }
virtual QByteArray serialize() const;
virtual bool deserialize(const QByteArray& data);
virtual void setMessageQueueToGUI(MessageQueue *queue) { m_guiMessageQueue = queue; }
virtual const QString& getDeviceDescription() const;
virtual int getSampleRate() const;
virtual quint64 getCenterFrequency() const;
virtual void setCenterFrequency(qint64 centerFrequency);
virtual bool handleMessage(const Message& message);
virtual int webapiSettingsGet(
SWGSDRangel::SWGDeviceSettings& response,
QString& errorMessage);
virtual int webapiSettingsPutPatch(
bool force,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response, // query + 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);
std::size_t getChannelIndex();
void getLORange(float& minF, float& maxF, float& stepF) const;
void getSRRange(float& minF, float& maxF, float& stepF) const;
void getLPRange(float& minF, float& maxF, float& stepF) const;
private:
DeviceSinkAPI *m_deviceAPI;
QMutex m_mutex;
XTRXOutputSettings m_settings;
XTRXOutputThread* m_XTRXOutputThread;
QString m_deviceDescription;
bool m_running;
DeviceXTRXShared m_deviceShared;
QNetworkAccessManager *m_networkManager;
QNetworkRequest m_networkRequest;
bool openDevice();
void closeDevice();
XTRXOutputThread *findThread();
void moveThreadToBuddy();
void suspendRxThread();
void resumeRxThread();
bool applySettings(const XTRXOutputSettings& settings, bool force = false, bool forceNCOFrequency = false);
void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const XTRXOutputSettings& settings);
void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response);
void webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const XTRXOutputSettings& settings, bool force);
void webapiReverseSendStartStop(bool start);
private slots:
void networkManagerFinished(QNetworkReply *reply);
};
#endif /* PLUGINS_SAMPLESINK_XTRXOUTPUT_XTRXOUTPUT_H_ */

View File

@ -0,0 +1,513 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <QDebug>
#include <QMessageBox>
#include "ui_xtrxoutputgui.h"
#include "gui/colormapper.h"
#include "gui/glspectrum.h"
#include "gui/crightclickenabler.h"
#include "gui/basicdevicesettingsdialog.h"
#include "dsp/dspengine.h"
#include "dsp/dspcommands.h"
#include "device/devicesinkapi.h"
#include "device/deviceuiset.h"
#include "xtrxoutputgui.h"
XTRXOutputGUI::XTRXOutputGUI(DeviceUISet *deviceUISet, QWidget* parent) :
QWidget(parent),
ui(new Ui::XTRXOutputGUI),
m_deviceUISet(deviceUISet),
m_settings(),
m_sampleRate(0),
m_lastEngineState((DSPDeviceSinkEngine::State)-1),
m_doApplySettings(true),
m_forceSettings(true),
m_statusCounter(0),
m_deviceStatusCounter(0)
{
m_XTRXOutput = (XTRXOutput*) m_deviceUISet->m_deviceSinkAPI->getSampleSink();
ui->setupUi(this);
float minF, maxF, stepF;
m_XTRXOutput->getLORange(minF, maxF, stepF);
ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
ui->centerFrequency->setValueRange(7, ((uint32_t) minF)/1000, ((uint32_t) maxF)/1000); // frequency dial is in kHz
m_XTRXOutput->getSRRange(minF, maxF, stepF);
ui->sampleRate->setColorMapper(ColorMapper(ColorMapper::GrayGreenYellow));
ui->sampleRate->setValueRange(8, (uint32_t) minF, (uint32_t) maxF);
m_XTRXOutput->getLPRange(minF, maxF, stepF);
ui->lpf->setColorMapper(ColorMapper(ColorMapper::GrayYellow));
ui->lpf->setValueRange(6, (minF/1000)+1, maxF/1000);
ui->ncoFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
ui->channelNumberText->setText(tr("#%1").arg(m_XTRXOutput->getChannelIndex()));
ui->hwInterpLabel->setText(QString::fromUtf8("H\u2193"));
ui->swInterpLabel->setText(QString::fromUtf8("S\u2193"));
connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware()));
connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
m_statusTimer.start(500);
CRightClickEnabler *startStopRightClickEnabler = new CRightClickEnabler(ui->startStop);
connect(startStopRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(openDeviceSettingsDialog(const QPoint &)));
displaySettings();
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
}
XTRXOutputGUI::~XTRXOutputGUI()
{
delete ui;
}
void XTRXOutputGUI::destroy()
{
delete this;
}
void XTRXOutputGUI::setName(const QString& name)
{
setObjectName(name);
}
QString XTRXOutputGUI::getName() const
{
return objectName();
}
void XTRXOutputGUI::resetToDefaults()
{
m_settings.resetToDefaults();
displaySettings();
sendSettings();
}
qint64 XTRXOutputGUI::getCenterFrequency() const
{
return m_settings.m_centerFrequency + (m_settings.m_ncoEnable ? m_settings.m_ncoFrequency : 0);
}
void XTRXOutputGUI::setCenterFrequency(qint64 centerFrequency)
{
m_settings.m_centerFrequency = centerFrequency - (m_settings.m_ncoEnable ? m_settings.m_ncoFrequency : 0);
displaySettings();
sendSettings();
}
QByteArray XTRXOutputGUI::serialize() const
{
return m_settings.serialize();
}
bool XTRXOutputGUI::deserialize(const QByteArray& data)
{
if (m_settings.deserialize(data))
{
displaySettings();
m_forceSettings = true;
sendSettings();
return true;
}
else
{
resetToDefaults();
return false;
}
}
bool XTRXOutputGUI::handleMessage(const Message& message)
{
if (DeviceXTRXShared::MsgReportBuddyChange::match(message))
{
DeviceXTRXShared::MsgReportBuddyChange& report = (DeviceXTRXShared::MsgReportBuddyChange&) message;
m_settings.m_devSampleRate = report.getDevSampleRate();
m_settings.m_log2HardInterp = report.getLog2HardDecimInterp();
if (!report.getRxElseTx()) {
m_settings.m_centerFrequency = report.getCenterFrequency();
}
blockApplySettings(true);
displaySettings();
blockApplySettings(false);
return true;
}
else if (DeviceXTRXShared::MsgReportClockSourceChange::match(message))
{
DeviceXTRXShared::MsgReportClockSourceChange& report = (DeviceXTRXShared::MsgReportClockSourceChange&) message;
m_settings.m_extClockFreq = report.getExtClockFeq();
m_settings.m_extClock = report.getExtClock();
blockApplySettings(true);
ui->extClock->setExternalClockFrequency(m_settings.m_extClockFreq);
ui->extClock->setExternalClockActive(m_settings.m_extClock);
blockApplySettings(false);
return true;
}
else if (XTRXOutput::MsgReportStreamInfo::match(message))
{
XTRXOutput::MsgReportStreamInfo& report = (XTRXOutput::MsgReportStreamInfo&) message;
if (report.getSuccess())
{
if (report.getActive()) {
ui->streamStatusLabel->setStyleSheet("QLabel { background-color : green; }");
} else {
ui->streamStatusLabel->setStyleSheet("QLabel { background-color : blue; }");
}
ui->fifoBar->setMaximum(report.getFifoSize());
ui->fifoBar->setValue(report.getFifoFilledCount());
ui->fifoBar->setToolTip(tr("FIFO fill %1/%2 samples").arg(QString::number(report.getFifoFilledCount())).arg(QString::number(report.getFifoSize())));
}
else
{
ui->streamStatusLabel->setStyleSheet("QLabel { background:rgb(79,79,79); }");
}
return true;
}
else if (DeviceXTRXShared::MsgReportDeviceInfo::match(message))
{
DeviceXTRXShared::MsgReportDeviceInfo& report = (DeviceXTRXShared::MsgReportDeviceInfo&) message;
ui->temperatureText->setText(tr("%1C").arg(QString::number(report.getTemperature(), 'f', 0)));
if (report.getGPSLocked()) {
ui->gpsStatusLabel->setStyleSheet("QLabel { background-color : green; }");
} else {
ui->gpsStatusLabel->setStyleSheet("QLabel { background:rgb(48,48,48); }");
}
return true;
}
else if (XTRXOutput::MsgStartStop::match(message))
{
XTRXOutput::MsgStartStop& notif = (XTRXOutput::MsgStartStop&) message;
blockApplySettings(true);
ui->startStop->setChecked(notif.getStartStop());
blockApplySettings(false);
return true;
}
return false;
}
void XTRXOutputGUI::handleInputMessages()
{
Message* message;
while ((message = m_inputMessageQueue.pop()) != 0)
{
if (DSPSignalNotification::match(*message))
{
DSPSignalNotification* notif = (DSPSignalNotification*) message;
m_sampleRate = notif->getSampleRate();
m_deviceCenterFrequency = notif->getCenterFrequency();
qDebug("XTRXInputGUI::handleInputMessages: DSPSignalNotification: SampleRate: %d, CenterFrequency: %llu", notif->getSampleRate(), notif->getCenterFrequency());
updateSampleRateAndFrequency();
delete message;
}
else
{
if (handleMessage(*message)) {
delete message;
}
}
}
}
void XTRXOutputGUI::updateDACRate()
{
uint32_t dacRate = m_settings.m_devSampleRate * (1<<m_settings.m_log2HardInterp);
if (dacRate < 100000000) {
ui->dacRateLabel->setText(tr("%1k").arg(QString::number(dacRate / 1000.0f, 'g', 5)));
} else {
ui->dacRateLabel->setText(tr("%1M").arg(QString::number(dacRate / 1000000.0f, 'g', 5)));
}
}
void XTRXOutputGUI::updateSampleRateAndFrequency()
{
m_deviceUISet->getSpectrum()->setSampleRate(m_sampleRate);
m_deviceUISet->getSpectrum()->setCenterFrequency(m_deviceCenterFrequency);
ui->deviceRateLabel->setText(tr("%1k").arg(QString::number(m_sampleRate / 1000.0f, 'g', 5)));
}
void XTRXOutputGUI::displaySettings()
{
ui->extClock->setExternalClockFrequency(m_settings.m_extClockFreq);
ui->extClock->setExternalClockActive(m_settings.m_extClock);
setCenterFrequencyDisplay();
ui->sampleRate->setValue(m_settings.m_devSampleRate);
ui->hwInterp->setCurrentIndex(m_settings.m_log2HardInterp);
ui->swInterp->setCurrentIndex(m_settings.m_log2SoftInterp);
updateDACRate();
ui->lpf->setValue(m_settings.m_lpfBW / 1000);
ui->gain->setValue(m_settings.m_gain);
ui->gainText->setText(tr("%1").arg(m_settings.m_gain));
ui->antenna->setCurrentIndex((int) m_settings.m_antennaPath - (int) XTRX_TX_H);
setNCODisplay();
ui->ncoEnable->setChecked(m_settings.m_ncoEnable);
}
void XTRXOutputGUI::setNCODisplay()
{
int ncoHalfRange = (m_settings.m_devSampleRate * (1<<(m_settings.m_log2HardInterp)))/2;
ui->ncoFrequency->setValueRange(
false,
8,
-ncoHalfRange,
ncoHalfRange);
ui->ncoFrequency->blockSignals(true);
ui->ncoFrequency->setToolTip(QString("NCO frequency shift in Hz (Range: +/- %1 kHz)").arg(ncoHalfRange/1000));
ui->ncoFrequency->setValue(m_settings.m_ncoFrequency);
ui->ncoFrequency->blockSignals(false);
}
void XTRXOutputGUI::setCenterFrequencyDisplay()
{
int64_t centerFrequency = m_settings.m_centerFrequency;
ui->centerFrequency->setToolTip(QString("Main center frequency in kHz (LO: %1 kHz)").arg(centerFrequency/1000));
if (m_settings.m_ncoEnable) {
centerFrequency += m_settings.m_ncoFrequency;
}
ui->centerFrequency->blockSignals(true);
ui->centerFrequency->setValue(centerFrequency < 0 ? 0 : (uint64_t) centerFrequency/1000); // kHz
ui->centerFrequency->blockSignals(false);
}
void XTRXOutputGUI::setCenterFrequencySetting(uint64_t kHzValue)
{
int64_t centerFrequency = kHzValue*1000;
if (m_settings.m_ncoEnable) {
centerFrequency -= m_settings.m_ncoFrequency;
}
m_settings.m_centerFrequency = centerFrequency < 0 ? 0 : (uint64_t) centerFrequency;
ui->centerFrequency->setToolTip(QString("Main center frequency in kHz (LO: %1 kHz)").arg(centerFrequency/1000));
}
void XTRXOutputGUI::sendSettings()
{
if(!m_updateTimer.isActive())
m_updateTimer.start(100);
}
void XTRXOutputGUI::updateHardware()
{
if (m_doApplySettings)
{
qDebug() << "XTRXOutputGUI::updateHardware";
XTRXOutput::MsgConfigureXTRX* message = XTRXOutput::MsgConfigureXTRX::create(m_settings, m_forceSettings);
m_XTRXOutput->getInputMessageQueue()->push(message);
m_forceSettings = false;
m_updateTimer.stop();
}
}
void XTRXOutputGUI::updateStatus()
{
int state = m_deviceUISet->m_deviceSinkAPI->state();
if(m_lastEngineState != state)
{
switch(state)
{
case DSPDeviceSinkEngine::StNotStarted:
ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
break;
case DSPDeviceSinkEngine::StIdle:
ui->startStop->setStyleSheet("QToolButton { background-color : blue; }");
break;
case DSPDeviceSinkEngine::StRunning:
ui->startStop->setStyleSheet("QToolButton { background-color : green; }");
break;
case DSPDeviceSinkEngine::StError:
ui->startStop->setStyleSheet("QToolButton { background-color : red; }");
QMessageBox::information(this, tr("Message"), m_deviceUISet->m_deviceSinkAPI->errorMessage());
break;
default:
break;
}
m_lastEngineState = state;
}
if (m_statusCounter < 1)
{
m_statusCounter++;
}
else
{
XTRXOutput::MsgGetStreamInfo* message = XTRXOutput::MsgGetStreamInfo::create();
m_XTRXOutput->getInputMessageQueue()->push(message);
m_statusCounter = 0;
}
if (m_deviceStatusCounter < 10)
{
m_deviceStatusCounter++;
}
else
{
if (m_deviceUISet->m_deviceSinkAPI->isBuddyLeader())
{
XTRXOutput::MsgGetDeviceInfo* message = XTRXOutput::MsgGetDeviceInfo::create();
m_XTRXOutput->getInputMessageQueue()->push(message);
}
m_deviceStatusCounter = 0;
}
}
void XTRXOutputGUI::blockApplySettings(bool block)
{
m_doApplySettings = !block;
}
void XTRXOutputGUI::on_startStop_toggled(bool checked)
{
if (m_doApplySettings)
{
XTRXOutput::MsgStartStop *message = XTRXOutput::MsgStartStop::create(checked);
m_XTRXOutput->getInputMessageQueue()->push(message);
}
}
void XTRXOutputGUI::on_centerFrequency_changed(quint64 value)
{
setCenterFrequencySetting(value);
sendSettings();
}
void XTRXOutputGUI::on_ncoFrequency_changed(qint64 value)
{
m_settings.m_ncoFrequency = value;
setCenterFrequencyDisplay();
sendSettings();
}
void XTRXOutputGUI::on_ncoEnable_toggled(bool checked)
{
m_settings.m_ncoEnable = checked;
setCenterFrequencyDisplay();
sendSettings();
}
void XTRXOutputGUI::on_sampleRate_changed(quint64 value)
{
m_settings.m_devSampleRate = value;
updateDACRate();
setNCODisplay();
sendSettings();}
void XTRXOutputGUI::on_hwInterp_currentIndexChanged(int index)
{
if ((index <0) || (index > 5))
return;
m_settings.m_log2HardInterp = index;
updateDACRate();
setNCODisplay();
sendSettings();
}
void XTRXOutputGUI::on_swInterp_currentIndexChanged(int index)
{
if ((index <0) || (index > 6))
return;
m_settings.m_log2SoftInterp = index;
sendSettings();
}
void XTRXOutputGUI::on_lpf_changed(quint64 value)
{
m_settings.m_lpfBW = value * 1000;
sendSettings();
}
void XTRXOutputGUI::on_gain_valueChanged(int value)
{
m_settings.m_gain = value;
ui->gainText->setText(tr("%1").arg(m_settings.m_gain));
sendSettings();
}
void XTRXOutputGUI::on_antenna_currentIndexChanged(int index)
{
m_settings.m_antennaPath = (xtrx_antenna_t) (index + (int) XTRX_TX_H);
sendSettings();
}
void XTRXOutputGUI::on_extClock_clicked()
{
m_settings.m_extClock = ui->extClock->getExternalClockActive();
m_settings.m_extClockFreq = ui->extClock->getExternalClockFrequency();
qDebug("XTRXOutputGUI::on_extClock_clicked: %u Hz %s", m_settings.m_extClockFreq, m_settings.m_extClock ? "on" : "off");
sendSettings();
}
void XTRXOutputGUI::on_pwrmode_currentIndexChanged(int index)
{
m_settings.m_pwrmode = index;
sendSettings();
}
void XTRXOutputGUI::openDeviceSettingsDialog(const QPoint& p)
{
BasicDeviceSettingsDialog dialog(this);
dialog.setUseReverseAPI(m_settings.m_useReverseAPI);
dialog.setReverseAPIAddress(m_settings.m_reverseAPIAddress);
dialog.setReverseAPIPort(m_settings.m_reverseAPIPort);
dialog.setReverseAPIDeviceIndex(m_settings.m_reverseAPIDeviceIndex);
dialog.move(p);
dialog.exec();
m_settings.m_useReverseAPI = dialog.useReverseAPI();
m_settings.m_reverseAPIAddress = dialog.getReverseAPIAddress();
m_settings.m_reverseAPIPort = dialog.getReverseAPIPort();
m_settings.m_reverseAPIDeviceIndex = dialog.getReverseAPIDeviceIndex();
sendSettings();
}

View File

@ -0,0 +1,99 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef PLUGINS_SAMPLESINK_XTRXOUTPUT_XTRXOUTPUTGUI_H_
#define PLUGINS_SAMPLESINK_XTRXOUTPUT_XTRXOUTPUTGUI_H_
#include <plugin/plugininstancegui.h>
#include <QTimer>
#include <QWidget>
#include "util/messagequeue.h"
#include "xtrxoutput.h"
class DeviceUISet;
namespace Ui {
class XTRXOutputGUI;
}
class XTRXOutputGUI : public QWidget, public PluginInstanceGUI {
Q_OBJECT
public:
explicit XTRXOutputGUI(DeviceUISet *deviceUISet, QWidget* parent = 0);
virtual ~XTRXOutputGUI();
virtual void destroy();
void setName(const QString& name);
QString getName() const;
void resetToDefaults();
virtual qint64 getCenterFrequency() const;
virtual void setCenterFrequency(qint64 centerFrequency);
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
virtual bool handleMessage(const Message& message);
private:
Ui::XTRXOutputGUI* ui;
DeviceUISet* m_deviceUISet;
XTRXOutput* m_XTRXOutput; //!< Same object as above but gives easy access to XTRXInput methods and attributes that are used intensively
XTRXOutputSettings m_settings;
QTimer m_updateTimer;
QTimer m_statusTimer;
int m_sampleRate;
quint64 m_deviceCenterFrequency; //!< Center frequency in device
int m_lastEngineState;
bool m_doApplySettings;
bool m_forceSettings;
int m_statusCounter;
int m_deviceStatusCounter;
MessageQueue m_inputMessageQueue;
void displaySettings();
void setNCODisplay();
void setCenterFrequencyDisplay();
void setCenterFrequencySetting(uint64_t kHzValue);
void sendSettings();
void updateSampleRateAndFrequency();
void updateDACRate();
void blockApplySettings(bool block);
private slots:
void handleInputMessages();
void on_startStop_toggled(bool checked);
void on_centerFrequency_changed(quint64 value);
void on_ncoFrequency_changed(qint64 value);
void on_ncoEnable_toggled(bool checked);
void on_sampleRate_changed(quint64 value);
void on_hwInterp_currentIndexChanged(int index);
void on_swInterp_currentIndexChanged(int index);
void on_lpf_changed(quint64 value);
void on_gain_valueChanged(int value);
void on_antenna_currentIndexChanged(int index);
void on_extClock_clicked();
void on_pwrmode_currentIndexChanged(int index);
void updateHardware();
void updateStatus();
void openDeviceSettingsDialog(const QPoint& p);
};
#endif /* PLUGINS_SAMPLESINK_XTRXOUTPUT_XTRXOUTPUTGUI_H_ */

View File

@ -0,0 +1,913 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>XTRXOutputGUI</class>
<widget class="QWidget" name="XTRXOutputGUI">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>370</width>
<height>290</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>360</width>
<height>290</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Sans</family>
<pointsize>9</pointsize>
</font>
</property>
<property name="windowTitle">
<string>XTRX output</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_freq">
<property name="topMargin">
<number>4</number>
</property>
<item>
<layout class="QVBoxLayout" name="freqLeftLayout">
<item>
<layout class="QHBoxLayout" name="freqLeftTopLayout">
<item>
<widget class="ButtonSwitch" name="startStop">
<property name="toolTip">
<string>start/stop generation</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/play.png</normaloff>
<normalon>:/stop.png</normalon>:/play.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="freqLeftBotLayout">
<item>
<widget class="QLabel" name="dacRateLabel">
<property name="minimumSize">
<size>
<width>54</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>ADC rate before hardware downsampling (k or MS/s)</string>
</property>
<property name="text">
<string>00000k</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="freqLeftSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="ValueDial" name="centerFrequency" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Mono</family>
<pointsize>20</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Main center frequency in kHz</string>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="freqRightLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<item>
<layout class="QHBoxLayout" name="freqRightTopLayout">
<item>
<widget class="QLabel" name="freqUnits">
<property name="text">
<string> kHz</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="channelNumberText">
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Channel number</string>
</property>
<property name="text">
<string>#0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="freqRightBotLayout">
<item>
<widget class="QLabel" name="deviceRateLabel">
<property name="minimumSize">
<size>
<width>54</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Baseband I/Q sample rate kS/s</string>
</property>
<property name="text">
<string>00000k</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>2</number>
</property>
<item>
<widget class="ButtonSwitch" name="ncoEnable">
<property name="toolTip">
<string>Enable the TSP NCO</string>
</property>
<property name="text">
<string>NCO</string>
</property>
</widget>
</item>
<item>
<widget class="ValueDialZ" name="ncoFrequency" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Mono</family>
<pointsize>12</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="toolTip">
<string>Center frequency with NCO engaged (kHz)</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="ncoUnits">
<property name="text">
<string>kHz</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="ExternalClockButton" name="extClock">
<property name="toolTip">
<string>External clock dialog</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/clocksource.png</normaloff>:/clocksource.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_lna">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="ncoSampleRateLayout">
<property name="topMargin">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="hwInterpLabel">
<property name="text">
<string>Hw</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="hwInterp">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>TSP hardware decimation factor</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>1</string>
</property>
</item>
<item>
<property name="text">
<string>2</string>
</property>
</item>
<item>
<property name="text">
<string>4</string>
</property>
</item>
<item>
<property name="text">
<string>8</string>
</property>
</item>
<item>
<property name="text">
<string>16</string>
</property>
</item>
<item>
<property name="text">
<string>32</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="swInterpLabel">
<property name="text">
<string>Sw</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="swInterp">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Software decimation factor</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>1</string>
</property>
</item>
<item>
<property name="text">
<string>2</string>
</property>
</item>
<item>
<property name="text">
<string>4</string>
</property>
</item>
<item>
<property name="text">
<string>8</string>
</property>
</item>
<item>
<property name="text">
<string>16</string>
</property>
</item>
<item>
<property name="text">
<string>32</string>
</property>
</item>
<item>
<property name="text">
<string>64</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="samplerateLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>SR</string>
</property>
</widget>
</item>
<item>
<widget class="ValueDial" name="sampleRate" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Mono</family>
<pointsize>12</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="toolTip">
<string>Device to host sample rate</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="samplerateUnit">
<property name="text">
<string>S/s</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_freq">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="lpfLayout">
<property name="topMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="lpfLabel">
<property name="text">
<string>LP</string>
</property>
</widget>
</item>
<item>
<widget class="ValueDial" name="lpf" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Mono</family>
<pointsize>12</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="toolTip">
<string>Analog lowpass filer bandwidth (kHz)</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lpfUnits">
<property name="text">
<string>kHz</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="pwrmodeLabel">
<property name="text">
<string>LMS Pwr</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="pwrmode">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Power mode</string>
</property>
<property name="currentIndex">
<number>4</number>
</property>
<item>
<property name="text">
<string>0 - Save Max</string>
</property>
</item>
<item>
<property name="text">
<string>1</string>
</property>
</item>
<item>
<property name="text">
<string>2</string>
</property>
</item>
<item>
<property name="text">
<string>3 - Economy</string>
</property>
</item>
<item>
<property name="text">
<string>4 - Optimal</string>
</property>
</item>
<item>
<property name="text">
<string>5</string>
</property>
</item>
<item>
<property name="text">
<string>6</string>
</property>
</item>
<item>
<property name="text">
<string>7 - Perf Max</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="gainLayout">
<property name="topMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="gainLabel">
<property name="text">
<string>Gain</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="gain">
<property name="toolTip">
<string>Global gain setting (dB)</string>
</property>
<property name="maximum">
<number>70</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>20</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="gainText">
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>18</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Global gain (dB)</string>
</property>
<property name="text">
<string>20dB</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="antennaLabel">
<property name="pixmap">
<pixmap resource="../../../sdrgui/resources/res.qrc">:/antenna.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="antenna">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Antenna select: No: none, Lo: 700:900M, Hi: 2:2.6G, Wi: wideband, T1: Tx1 LB, T2: Tx2 LB</string>
</property>
<item>
<property name="text">
<string>Hi</string>
</property>
</item>
<item>
<property name="text">
<string>Wi</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="statusLayout">
<property name="topMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="streamStatusLabel">
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Green when stream is reporting data</string>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../../../sdrgui/resources/res.qrc">:/stream.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="gpsStatusLabel">
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Green when GPS is locked</string>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../../../sdrgui/resources/res.qrc">:/gps.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="fifoBar">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16</height>
</size>
</property>
<property name="font">
<font>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>FIFO fill status</string>
</property>
<property name="styleSheet">
<string notr="true">QProgressBar{border: 2px solid rgb(79, 79, 79); text-align: center;}
QToolTip{background-color: white; color: black;}</string>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="temperatureText">
<property name="minimumSize">
<size>
<width>24</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Board temperature (degrees C)</string>
</property>
<property name="text">
<string>00C</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_vga2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="padLayout">
<item>
<spacer name="verticalPadSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ValueDial</class>
<extends>QWidget</extends>
<header>gui/valuedial.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ButtonSwitch</class>
<extends>QToolButton</extends>
<header>gui/buttonswitch.h</header>
</customwidget>
<customwidget>
<class>ExternalClockButton</class>
<extends>QToolButton</extends>
<header>gui/externalclockbutton.h</header>
</customwidget>
<customwidget>
<class>ValueDialZ</class>
<extends>QWidget</extends>
<header>gui/valuedialz.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../../../sdrgui/resources/res.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,127 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 Edouard Griffiths, F4EXB //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QtPlugin>
#include <regex>
#include <string>
#include "xtrx_api.h"
#include "plugin/pluginapi.h"
#include "util/simpleserializer.h"
#include "device/devicesinkapi.h"
#include "xtrx/devicextrxparam.h"
#ifdef SERVER_MODE
#include "xtrxoutput.h"
#else
#include "xtrxoutputgui.h"
#endif
#include "../xtrxoutput/xtrxoutputplugin.h"
const PluginDescriptor XTRXOutputPlugin::m_pluginDescriptor = {
QString("XTRX Output"),
QString("4.4.0"),
QString("(c) Edouard Griffiths, F4EXB"),
QString("https://github.com/f4exb/sdrangel"),
true,
QString("https://github.com/f4exb/sdrangel")
};
const QString XTRXOutputPlugin::m_hardwareID = "XTRX";
const QString XTRXOutputPlugin::m_deviceTypeID = XTRXOUTPUT_DEVICE_TYPE_ID;
XTRXOutputPlugin::XTRXOutputPlugin(QObject* parent) :
QObject(parent)
{
}
const PluginDescriptor& XTRXOutputPlugin::getPluginDescriptor() const
{
return m_pluginDescriptor;
}
void XTRXOutputPlugin::initPlugin(PluginAPI* pluginAPI)
{
pluginAPI->registerSampleSink(m_deviceTypeID, this);
}
PluginInterface::SamplingDevices XTRXOutputPlugin::enumSampleSinks()
{
SamplingDevices result;
xtrx_device_info_t devs[32];
int res = xtrx_discovery(devs, 32);
int i;
for (i = 0; i < res; i++) {
DeviceXTRXParams XTRXParams;
for (unsigned int j = 0; j < XTRXParams.m_nbTxChannels; j++)
{
qDebug("XTRXInputPlugin::enumSampleSinks: device #%d channel %u: %s", i, j, devs[i].uniqname);
QString displayedName(QString("XTRX[%1:%2] %3").arg(i).arg(j).arg(devs[i].uniqname));
result.append(SamplingDevice(displayedName,
m_hardwareID,
m_deviceTypeID,
QString(devs[i].uniqname),
i,
PluginInterface::SamplingDevice::PhysicalDevice,
false,
XTRXParams.m_nbTxChannels,
j));
}
}
return result;
}
#ifdef SERVER_MODE
PluginInstanceGUI* XTRXOutputPlugin::createSampleSinkPluginInstanceGUI(
const QString& sinkId __attribute((unused)),
QWidget **widget __attribute((unused)),
DeviceUISet *deviceUISet __attribute((unused)))
{
return 0;
}
#else
PluginInstanceGUI* XTRXOutputPlugin::createSampleSinkPluginInstanceGUI(
const QString& sinkId,
QWidget **widget,
DeviceUISet *deviceUISet)
{
if(sinkId == m_deviceTypeID)
{
XTRXOutputGUI* gui = new XTRXOutputGUI(deviceUISet);
*widget = gui;
return gui;
}
else
{
return 0;
}
}
#endif
DeviceSampleSink* XTRXOutputPlugin::createSampleSinkPluginInstanceOutput(const QString& sinkId, DeviceSinkAPI *deviceAPI)
{
if(sinkId == m_deviceTypeID)
{
XTRXOutput* output = new XTRXOutput(deviceAPI);
return output;
}
else
{
return 0;
}
}

View File

@ -0,0 +1,53 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef PLUGINS_SAMPLESOURCE_LIMESDROUTPUT_LIMESDROUTPUTPLUGIN_H_
#define PLUGINS_SAMPLESOURCE_LIMESDROUTPUT_LIMESDROUTPUTPLUGIN_H_
#include <QObject>
#include "plugin/plugininterface.h"
class PluginAPI;
#define XTRXOUTPUT_DEVICE_TYPE_ID "sdrangel.samplesink.xtrx"
class XTRXOutputPlugin : public QObject, public PluginInterface {
Q_OBJECT
Q_INTERFACES(PluginInterface)
Q_PLUGIN_METADATA(IID XTRXOUTPUT_DEVICE_TYPE_ID)
public:
explicit XTRXOutputPlugin(QObject* parent = 0);
const PluginDescriptor& getPluginDescriptor() const;
void initPlugin(PluginAPI* pluginAPI);
virtual SamplingDevices enumSampleSinks();
virtual PluginInstanceGUI* createSampleSinkPluginInstanceGUI(
const QString& sinkId,
QWidget **widget,
DeviceUISet *deviceUISet);
virtual DeviceSampleSink* createSampleSinkPluginInstanceOutput(const QString& sinkId, DeviceSinkAPI *deviceAPI);
static const QString m_hardwareID;
static const QString m_deviceTypeID;
private:
static const PluginDescriptor m_pluginDescriptor;
};
#endif /* PLUGINS_SAMPLESOURCE_LIMESDROUTPUT_LIMESDROUTPUTPLUGIN_H_ */

View File

@ -0,0 +1,117 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include "../xtrxoutput/xtrxoutputsettings.h"
#include "util/simpleserializer.h"
XTRXOutputSettings::XTRXOutputSettings()
{
resetToDefaults();
}
void XTRXOutputSettings::resetToDefaults()
{
m_centerFrequency = 435000*1000;
m_devSampleRate = 5e6;
m_log2HardInterp = 1;
m_log2SoftInterp = 4;
m_lpfBW = 4.5e6f;
m_gain = 20;
m_ncoEnable = true;
m_ncoFrequency = 500000;
m_antennaPath = XTRX_TX_H;
m_extClock = false;
m_extClockFreq = 0; // Auto
m_pwrmode = 1;
m_useReverseAPI = false;
m_reverseAPIAddress = "127.0.0.1";
m_reverseAPIPort = 8888;
m_reverseAPIDeviceIndex = 0;
}
QByteArray XTRXOutputSettings::serialize() const
{
SimpleSerializer s(1);
s.writeDouble(1, m_devSampleRate);
s.writeU32(2, m_log2HardInterp);
s.writeU32(3, m_log2SoftInterp);
s.writeFloat(4, m_lpfBW);
s.writeU32(5, m_gain);
s.writeBool(6, m_ncoEnable);
s.writeS32(7, m_ncoFrequency);
s.writeS32(8, (int) m_antennaPath);
s.writeBool(9, m_extClock);
s.writeU32(10, m_extClockFreq);
s.writeU32(11, m_pwrmode);
s.writeBool(12, m_useReverseAPI);
s.writeString(13, m_reverseAPIAddress);
s.writeU32(14, m_reverseAPIPort);
s.writeU32(15, m_reverseAPIDeviceIndex);
return s.final();
}
bool XTRXOutputSettings::deserialize(const QByteArray& data)
{
SimpleDeserializer d(data);
if (!d.isValid())
{
resetToDefaults();
return false;
}
if (d.getVersion() == 1)
{
int intval;
uint32_t uintval;
d.readDouble(1, &m_devSampleRate, 5e6);
d.readU32(2, &m_log2HardInterp, 2);
d.readU32(3, &m_log2SoftInterp, 0);
d.readFloat(4, &m_lpfBW, 1.5e6);
d.readU32(5, &m_gain, 20);
d.readBool(6, &m_ncoEnable, true);
d.readS32(7, &m_ncoFrequency, 500000);
d.readS32(8, &intval, 0);
m_antennaPath = (xtrx_antenna_t) intval;
d.readBool(9, &m_extClock, false);
d.readU32(10, &m_extClockFreq, 0);
d.readU32(11, &m_pwrmode, 2);
d.readBool(12, &m_useReverseAPI, false);
d.readString(13, &m_reverseAPIAddress, "127.0.0.1");
d.readU32(14, &uintval, 0);
if ((uintval > 1023) && (uintval < 65535)) {
m_reverseAPIPort = uintval;
} else {
m_reverseAPIPort = 8888;
}
d.readU32(15, &uintval, 0);
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
return true;
}
else
{
resetToDefaults();
return false;
}
}

View File

@ -0,0 +1,58 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef PLUGINS_SAMPLESINK_XTRXOUTPUT_XTRXOUTPUTSETTINGS_H_
#define PLUGINS_SAMPLESINK_XTRXOUTPUT_XTRXOUTPUTSETTINGS_H_
#include <stdint.h>
#include <QByteArray>
#include <QString>
#include "xtrx_api.h"
/**
* These are the settings individual to each hardware channel or software Tx chain
* Plus the settings to be saved in the presets
*/
struct XTRXOutputSettings
{
// global settings to be saved
uint64_t m_centerFrequency;
double m_devSampleRate;
uint32_t m_log2HardInterp;
// channel settings
uint32_t m_log2SoftInterp;
float m_lpfBW; //!< LMS analog lowpass filter bandwidth (Hz)
uint32_t m_gain; //!< Optimally distributed gain (dB)
bool m_ncoEnable; //!< Enable TSP NCO and mixing
int m_ncoFrequency; //!< Actual NCO frequency (the resulting frequency with mixing is displayed)
xtrx_antenna_t m_antennaPath;
bool m_extClock; //!< True if external clock source
uint32_t m_extClockFreq; //!< Frequency (Hz) of external clock source
uint32_t m_pwrmode;
bool m_useReverseAPI;
QString m_reverseAPIAddress;
uint16_t m_reverseAPIPort;
uint16_t m_reverseAPIDeviceIndex;
XTRXOutputSettings();
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
};
#endif /* PLUGINS_SAMPLESINK_XTRXOUTPUT_XTRXOUTPUTSETTINGS_H_ */

View File

@ -0,0 +1,333 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <chrono>
#include <thread>
#include "xtrx/devicextrx.h"
#include "dsp/samplesourcefifo.h"
#include "xtrxoutputthread.h"
XTRXOutputThread::XTRXOutputThread(struct xtrx_dev *dev, unsigned int nbChannels, unsigned int uniqueChannelIndex, QObject* parent) :
QThread(parent),
m_running(false),
m_dev(dev),
m_nbChannels(nbChannels),
m_uniqueChannelIndex(uniqueChannelIndex)
{
qDebug("XTRXOutputThread::XTRXOutputThread");
m_channels = new Channel[2];
m_buf = new qint16[2*DeviceXTRX::blockSize*nbChannels];
}
XTRXOutputThread::~XTRXOutputThread()
{
qDebug("XTRXOutputThread::~XTRXOutputThread");
if (m_running) {
stopWork();
}
delete[] m_buf;
delete[] m_channels;
}
void XTRXOutputThread::startWork()
{
m_startWaitMutex.lock();
start();
while(!m_running) {
m_startWaiter.wait(&m_startWaitMutex, 100);
}
m_startWaitMutex.unlock();
}
void XTRXOutputThread::stopWork()
{
m_running = false;
wait();
}
unsigned int XTRXOutputThread::getNbFifos()
{
unsigned int fifoCount = 0;
for (unsigned int i = 0; i < 2; i++)
{
if (m_channels[i].m_sampleFifo) {
fifoCount++;
}
}
return fifoCount;
}
void XTRXOutputThread::setLog2Interpolation(unsigned int channel, unsigned int log2_interp)
{
if (channel < 2) {
m_channels[channel].m_log2Interp = log2_interp;
}
}
unsigned int XTRXOutputThread::getLog2Interpolation(unsigned int channel) const
{
if (channel < 2) {
return m_channels[channel].m_log2Interp;
} else {
return 0;
}
}
void XTRXOutputThread::setFifo(unsigned int channel, SampleSourceFifo *sampleFifo)
{
if (channel < 2) {
m_channels[channel].m_sampleFifo = sampleFifo;
}
}
SampleSourceFifo *XTRXOutputThread::getFifo(unsigned int channel)
{
if (channel < 2) {
return m_channels[channel].m_sampleFifo;
} else {
return 0;
}
}
void XTRXOutputThread::run()
{
int res;
m_running = true;
m_startWaiter.wakeAll();
unsigned int nbFifos = getNbFifos();
if ((m_nbChannels != 0) && (nbFifos != 0))
{
xtrx_run_params params;
xtrx_run_params_init(&params);
params.dir = XTRX_TX;
params.tx_repeat_buf = 0;
params.tx.paketsize = DeviceXTRX::blockSize;
params.tx.chs = XTRX_CH_AB;
params.tx.wfmt = XTRX_WF_16;
params.tx.hfmt = XTRX_IQ_INT16;
if (m_nbChannels == 1)
{
qDebug("XTRXOutputThread::run: SO mode for channel #%u", m_uniqueChannelIndex);
params.tx.flags |= XTRX_RSP_SISO_MODE;
if (m_uniqueChannelIndex == 1) {
params.tx.flags |= XTRX_RSP_SWAP_AB;
}
}
res = xtrx_run_ex(m_dev, &params);
if (res != 0)
{
qCritical("XTRXOutputThread::run: could not start stream err:%d", res);
m_running = false;
}
else
{
std::this_thread::sleep_for(std::chrono::milliseconds(50));
qDebug("XTRXOutputThread::run: stream started");
}
const unsigned int elemSize = 4; // XTRX uses 4 byte I+Q samples
std::vector<std::vector<char>> buffMem(m_nbChannels, std::vector<char>(elemSize*DeviceXTRX::blockSize));
std::vector<void *> buffs(m_nbChannels);
master_ts ts = 4096*1024;
for (std::size_t i = 0; i < m_nbChannels; i++) {
buffs[i] = buffMem[i].data();
}
xtrx_send_ex_info_t nfo;
nfo.samples = DeviceXTRX::blockSize;
nfo.buffer_count = m_nbChannels;
nfo.buffers = (void* const*) buffs.data();
nfo.flags = 0; //XTRX_TX_SEND_ZEROS;
nfo.ts = ts;
while (m_running)
{
// if (m_nbChannels > 1) {
// callbackMO((qint16*) buffs[0], (qint16*) buffs[1], nfo.samples);
// } else {
// callbackSO((qint16*) buffs[0], nfo.samples);
// }
callbackSO((qint16*) buffs[0], nfo.samples);
res = xtrx_send_sync_ex(m_dev, &nfo);
if (res < 0)
{
qCritical("XTRXOutputThread::run send error: %d", res);
qDebug("XTRXOutputThread::run: out_samples: %u out_flags: %u", nfo.out_samples, nfo.out_flags);
break;
}
nfo.ts += DeviceXTRX::blockSize;
}
res = xtrx_stop(m_dev, XTRX_TX);
if (res != 0)
{
qCritical("XTRXOutputThread::run: could not stop stream");
}
else
{
std::this_thread::sleep_for(std::chrono::milliseconds(50));
qDebug("XTRXOutputThread::run: stream stopped");
}
}
else
{
qWarning("XTRXOutputThread::run: no channels or FIFO allocated. Aborting");
}
m_running = false;
}
void XTRXOutputThread::callback(qint16* buf, qint32 len)
{
if (m_channels[m_uniqueChannelIndex].m_sampleFifo)
{
float bal = m_channels[m_uniqueChannelIndex].m_sampleFifo->getRWBalance();
if (bal < -0.25) {
qDebug("XTRXOutputThread::callbackSO: read lags: %f", bal);
} else if (bal > 0.25) {
qDebug("XTRXOutputThread::callbackSO: read leads: %f", bal);
}
SampleVector::iterator beginRead;
m_channels[m_uniqueChannelIndex].m_sampleFifo->readAdvance(beginRead, len/(1<<m_channels[m_uniqueChannelIndex].m_log2Interp));
beginRead -= len;
if (m_channels[m_uniqueChannelIndex].m_log2Interp == 0)
{
m_channels[m_uniqueChannelIndex].m_interpolators.interpolate1(&beginRead, buf, len*2);
}
else
{
switch (m_channels[m_uniqueChannelIndex].m_log2Interp)
{
case 1:
m_channels[m_uniqueChannelIndex].m_interpolators.interpolate2_cen(&beginRead, buf, len*2);
break;
case 2:
m_channels[m_uniqueChannelIndex].m_interpolators.interpolate4_cen(&beginRead, buf, len*2);
break;
case 3:
m_channels[m_uniqueChannelIndex].m_interpolators.interpolate8_cen(&beginRead, buf, len*2);
break;
case 4:
m_channels[m_uniqueChannelIndex].m_interpolators.interpolate16_cen(&beginRead, buf, len*2);
break;
case 5:
m_channels[m_uniqueChannelIndex].m_interpolators.interpolate32_cen(&beginRead, buf, len*2);
break;
case 6:
m_channels[m_uniqueChannelIndex].m_interpolators.interpolate64_cen(&beginRead, buf, len*2);
break;
default:
break;
}
}
}
else
{
std::fill(buf, buf+2*len, 0);
}
}
void XTRXOutputThread::callbackSO(qint16* buf, qint32 len)
{
if (m_channels[m_uniqueChannelIndex].m_sampleFifo)
{
float bal = m_channels[m_uniqueChannelIndex].m_sampleFifo->getRWBalance();
if (bal < -0.25) {
qDebug("XTRXOutputThread::callbackSO: read lags: %f", bal);
} else if (bal > 0.25) {
qDebug("XTRXOutputThread::callbackSO: read leads: %f", bal);
}
SampleVector::iterator beginRead;
m_channels[m_uniqueChannelIndex].m_sampleFifo->readAdvance(beginRead, len/(1<<m_channels[m_uniqueChannelIndex].m_log2Interp));
beginRead -= len;
if (m_channels[m_uniqueChannelIndex].m_log2Interp == 0)
{
m_channels[m_uniqueChannelIndex].m_interpolators.interpolate1(&beginRead, buf, len*2);
}
else
{
switch (m_channels[m_uniqueChannelIndex].m_log2Interp)
{
case 1:
m_channels[m_uniqueChannelIndex].m_interpolators.interpolate2_cen(&beginRead, buf, len*2);
break;
case 2:
m_channels[m_uniqueChannelIndex].m_interpolators.interpolate4_cen(&beginRead, buf, len*2);
break;
case 3:
m_channels[m_uniqueChannelIndex].m_interpolators.interpolate8_cen(&beginRead, buf, len*2);
break;
case 4:
m_channels[m_uniqueChannelIndex].m_interpolators.interpolate16_cen(&beginRead, buf, len*2);
break;
case 5:
m_channels[m_uniqueChannelIndex].m_interpolators.interpolate32_cen(&beginRead, buf, len*2);
break;
case 6:
m_channels[m_uniqueChannelIndex].m_interpolators.interpolate64_cen(&beginRead, buf, len*2);
break;
default:
break;
}
}
}
else
{
std::fill(buf, buf+2*len, 0);
}
}
void XTRXOutputThread::callbackMO(qint16* buf0, qint16* buf1, qint32 len)
{
unsigned int uniqueChannelIndex = m_uniqueChannelIndex;
// channel 0
m_uniqueChannelIndex = 0;
callbackSO(buf0, len);
// channel 1
m_uniqueChannelIndex = 1;
callbackSO(buf1, len);
m_uniqueChannelIndex = uniqueChannelIndex;
}

View File

@ -0,0 +1,82 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef PLUGINS_SAMPLESOURCE_XTRXOUTPUT_XTRXOUTPUTTHREAD_H_
#define PLUGINS_SAMPLESOURCE_XTRXOUTPUT_XTRXOUTPUTTHREAD_H_
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
#include "xtrx_api.h"
#include "dsp/samplesourcefifo.h"
#include "dsp/interpolators.h"
#include "xtrx/devicextrxshared.h"
struct xtrx_dev;
class XTRXOutputThread : public QThread, public DeviceXTRXShared::ThreadInterface
{
Q_OBJECT
public:
XTRXOutputThread(struct xtrx_dev *dev, unsigned int nbChannels, unsigned int uniqueChannelIndex = 0, QObject* parent = 0);
~XTRXOutputThread();
virtual void startWork();
virtual void stopWork();
virtual bool isRunning() { return m_running; }
unsigned int getNbChannels() const { return m_nbChannels; }
void setLog2Interpolation(unsigned int channel, unsigned int log2_interp);
unsigned int getLog2Interpolation(unsigned int channel) const;
void setFifo(unsigned int channel, SampleSourceFifo *sampleFifo);
SampleSourceFifo *getFifo(unsigned int channel);
private:
struct Channel
{
SampleSourceFifo* m_sampleFifo;
unsigned int m_log2Interp;
Interpolators<qint16, SDR_TX_SAMP_SZ, 12> m_interpolators;
Channel() :
m_sampleFifo(0),
m_log2Interp(0)
{}
~Channel()
{}
};
QMutex m_startWaitMutex;
QWaitCondition m_startWaiter;
bool m_running;
struct xtrx_dev *m_dev;
Channel *m_channels; //!< Array of channels dynamically allocated for the given number of Rx channels
qint16 *m_buf; //!< Full buffer for SISO or MIMO operation
unsigned int m_nbChannels;
unsigned int m_uniqueChannelIndex;
void run();
unsigned int getNbFifos();
void callback(qint16* buf, qint32 len);
void callbackSO(qint16* buf, qint32 len);
void callbackMO(qint16* buf0, qint16* buf1, qint32 len);
};
#endif /* PLUGINS_SAMPLESOURCE_XTRXOUTPUT_XTRXOUTPUTTHREAD_H_ */

View File

@ -305,6 +305,7 @@ bool XTRXInput::start()
delete xtrxInputThread;
xtrxInputThread = new XTRXInputThread(m_deviceShared.m_dev->getDevice(), 2); // MI mode (2 channels)
m_XTRXInputThread = xtrxInputThread; // take ownership
m_deviceShared.m_thread = xtrxInputThread;
for (int i = 0; i < 2; i++) // restore original FIFO references
{
@ -316,8 +317,10 @@ bool XTRXInput::start()
const std::vector<DeviceSourceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies();
std::vector<DeviceSourceAPI*>::const_iterator it = sourceBuddies.begin();
for (; it != sourceBuddies.end(); ++it) {
for (; it != sourceBuddies.end(); ++it)
{
((DeviceXTRXShared*) (*it)->getBuddySharedPtr())->m_source->setThread(0);
((DeviceXTRXShared*) (*it)->getBuddySharedPtr())->m_thread = 0;
}
// was used as temporary storage:
@ -336,6 +339,7 @@ bool XTRXInput::start()
qDebug("XTRXInput::start: allocate thread and take ownership");
xtrxInputThread = new XTRXInputThread(m_deviceShared.m_dev->getDevice(), 1, requestedChannel);
m_XTRXInputThread = xtrxInputThread; // take ownership
m_deviceShared.m_thread = xtrxInputThread;
needsStart = true;
}
@ -387,13 +391,16 @@ void XTRXInput::stop()
xtrxInputThread->stopWork();
delete xtrxInputThread;
m_XTRXInputThread = 0;
m_deviceShared.m_thread = 0;
// remove old thread address from buddies (reset in all buddies)
const std::vector<DeviceSourceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies();
std::vector<DeviceSourceAPI*>::const_iterator it = sourceBuddies.begin();
for (; it != sourceBuddies.end(); ++it) {
for (; it != sourceBuddies.end(); ++it)
{
((DeviceXTRXShared*) (*it)->getBuddySharedPtr())->m_source->setThread(0);
((DeviceXTRXShared*) (*it)->getBuddySharedPtr())->m_thread = 0;
}
}
else if (nbOriginalChannels == 2) // Reduce from MI to SI by deleting and re-creating the thread
@ -401,10 +408,10 @@ void XTRXInput::stop()
qDebug("XTRXInput::stop: MI mode. Reduce by deleting and re-creating the thread");
xtrxInputThread->stopWork();
delete xtrxInputThread;
m_XTRXInputThread = 0;
xtrxInputThread = new XTRXInputThread(m_deviceShared.m_dev->getDevice(), 1, requestedChannel);
m_XTRXInputThread = xtrxInputThread; // take ownership
m_deviceShared.m_thread = xtrxInputThread;
xtrxInputThread->setFifo(requestedChannel, &m_sampleFifo);
xtrxInputThread->setLog2Decimation(requestedChannel, m_settings.m_log2SoftDecim);
@ -412,8 +419,10 @@ void XTRXInput::stop()
const std::vector<DeviceSourceAPI*>& sourceBuddies = m_deviceAPI->getSourceBuddies();
std::vector<DeviceSourceAPI*>::const_iterator it = sourceBuddies.begin();
for (; it != sourceBuddies.end(); ++it) {
for (; it != sourceBuddies.end(); ++it)
{
((DeviceXTRXShared*) (*it)->getBuddySharedPtr())->m_source->setThread(0);
((DeviceXTRXShared*) (*it)->getBuddySharedPtr())->m_thread = 0;
}
xtrxInputThread->startWork();
@ -425,58 +434,42 @@ void XTRXInput::stop()
void XTRXInput::suspendTxThread()
{
// TODO: activate when output is managed
// XTRXOutputThread *xtrxOutputThread = 0;
//
// // find a buddy that has allocated the thread
// const std::vector<DeviceSinkAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
// std::vector<DeviceSinkAPI*>::const_iterator itSink = sinkBuddies.begin()
//
// for (; itSink != sinkBuddies.end(); ++itSink)
// {
// XTRXOutput *buddySink = ((DeviceXTRXShared*) (*itSink)->getBuddySharedPtr())->m_sink;
//
// if (buddySink)
// {
// xtrxOutputThread = buddySink->getThread();
//
// if (xtrxOutputThread) {
// break;
// }
// }
// }
//
// if (xtrxOutputThread) {
// xtrxOutputThread->stopWork();
// }
const std::vector<DeviceSinkAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
std::vector<DeviceSinkAPI*>::const_iterator itSink = sinkBuddies.begin();
qDebug("XTRXInput::suspendTxThread (%lu)", sinkBuddies.size());
for (; itSink != sinkBuddies.end(); ++itSink)
{
DeviceXTRXShared *buddySharedPtr = (DeviceXTRXShared *) (*itSink)->getBuddySharedPtr();
if ((buddySharedPtr->m_thread) && buddySharedPtr->m_thread->isRunning())
{
buddySharedPtr->m_thread->stopWork();
buddySharedPtr->m_threadWasRunning = true;
}
else
{
buddySharedPtr->m_threadWasRunning = false;
}
}
}
void XTRXInput::resumeTxThread()
{
// TODO: activate when output is managed
// XTRXOutputThread *xtrxOutputThread = 0;
//
// // find a buddy that has allocated the thread
// const std::vector<DeviceSinkAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
// std::vector<DeviceSinkAPI*>::const_iterator itSink = sinkBuddies.begin()
//
// for (; itSink != sinkBuddies.end(); ++itSink)
// {
// XTRXOutput *buddySink = ((DeviceXTRXShared*) (*itSink)->getBuddySharedPtr())->m_sink;
//
// if (buddySink)
// {
// xtrxOutputThread = buddySink->getThread();
//
// if (xtrxOutputThread) {
// break;
// }
// }
// }
//
// if (xtrxOutputThread) {
// xtrxOutputThread->startWork();
// }
const std::vector<DeviceSinkAPI*>& sinkBuddies = m_deviceAPI->getSinkBuddies();
std::vector<DeviceSinkAPI*>::const_iterator itSink = sinkBuddies.begin();
qDebug("XTRXInput::resumeTxThread (%lu)", sinkBuddies.size());
for (; itSink != sinkBuddies.end(); ++itSink)
{
DeviceXTRXShared *buddySharedPtr = (DeviceXTRXShared *) (*itSink)->getBuddySharedPtr();
if (buddySharedPtr->m_threadWasRunning) {
buddySharedPtr->m_thread->startWork();
}
}
}
QByteArray XTRXInput::serialize() const
@ -616,9 +609,12 @@ bool XTRXInput::handleMessage(const Message& message)
m_settings.m_centerFrequency + ncoShift);
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
DeviceXTRXShared::MsgReportBuddyChange *reportToGUI = DeviceXTRXShared::MsgReportBuddyChange::create(
m_settings.m_devSampleRate, m_settings.m_log2HardDecim, m_settings.m_centerFrequency, true);
getMessageQueueToGUI()->push(reportToGUI);
if (getMessageQueueToGUI())
{
DeviceXTRXShared::MsgReportBuddyChange *reportToGUI = DeviceXTRXShared::MsgReportBuddyChange::create(
m_settings.m_devSampleRate, m_settings.m_log2HardDecim, m_settings.m_centerFrequency, true);
getMessageQueueToGUI()->push(reportToGUI);
}
return true;
}
@ -629,9 +625,12 @@ bool XTRXInput::handleMessage(const Message& message)
m_settings.m_extClock = report.getExtClock();
m_settings.m_extClockFreq = report.getExtClockFeq();
DeviceXTRXShared::MsgReportClockSourceChange *reportToGUI = DeviceXTRXShared::MsgReportClockSourceChange::create(
m_settings.m_extClock, m_settings.m_extClockFreq);
getMessageQueueToGUI()->push(reportToGUI);
if (getMessageQueueToGUI())
{
DeviceXTRXShared::MsgReportClockSourceChange *reportToGUI = DeviceXTRXShared::MsgReportClockSourceChange::create(
m_settings.m_extClock, m_settings.m_extClockFreq);
getMessageQueueToGUI()->push(reportToGUI);
}
return true;
}

View File

@ -94,8 +94,8 @@ public:
class MsgReportStreamInfo : public Message {
MESSAGE_CLASS_DECLARATION
public:
bool getSuccess() const { return m_success; }
public:
bool getSuccess() const { return m_success; }
bool getActive() const { return m_active; }
uint32_t getFifoFilledCount() const { return m_fifoFilledCount; }
uint32_t getFifoSize() const { return m_fifoSize; }

View File

@ -36,10 +36,10 @@
const PluginDescriptor XTRXInputPlugin::m_pluginDescriptor = {
QString("XTRX Input"),
QString("4.4.0"),
QString("(c) Sergey Kostanbaev, Fairwaves"),
QString("https://github.com/xtrx-sdr/sdrangel"),
QString("(c) Edouard Griffiths, F4EXB"),
QString("https://github.com/f4exb/sdrangel"),
true,
QString("https://github.com/xtrx-sdr/sdrangel")
QString("https://github.com/f4exb/sdrangel")
};
const QString XTRXInputPlugin::m_hardwareID = "XTRX";
@ -113,24 +113,6 @@ PluginInstanceGUI* XTRXInputPlugin::createSampleSourcePluginInstanceGUI(
}
#endif
bool XTRXInputPlugin::findSerial(const char *lmsInfoStr, std::string& serial)
{
std::regex serial_reg("serial=([0-9,A-F]+)");
std::string input(lmsInfoStr);
std::smatch result;
std::regex_search(input, result, serial_reg);
if (result[1].str().length()>0)
{
serial = result[1].str();
return true;
}
else
{
return false;
}
}
DeviceSampleSource *XTRXInputPlugin::createSampleSourcePluginInstanceInput(const QString& sourceId, DeviceSourceAPI *deviceAPI)
{
if (sourceId == m_deviceTypeID)

View File

@ -48,7 +48,6 @@ public:
private:
static const PluginDescriptor m_pluginDescriptor;
static bool findSerial(const char *lmsInfoStr, std::string& serial);
};

View File

@ -19,8 +19,6 @@
#include <chrono>
#include <thread>
#include "xtrx_api.h"
#include "xtrx/devicextrx.h"
#include "xtrxinputsettings.h"
#include "xtrxinputthread.h"

View File

@ -30,7 +30,7 @@
struct xtrx_dev;
class XTRXInputThread : public QThread
class XTRXInputThread : public QThread, public DeviceXTRXShared::ThreadInterface
{
Q_OBJECT

View File

@ -33,6 +33,11 @@ if(LIBUSB_FOUND AND SOAPYSDR_FOUND)
add_subdirectory(soapysdroutput)
endif()
find_package(LibXTRX)
if(LIBXTRX_FOUND)
add_subdirectory(xtrxoutput)
endif(LIBXTRX_FOUND)
if (BUILD_DEBIAN)
add_subdirectory(bladerf1output)
add_subdirectory(bladerf2output)

View File

@ -0,0 +1,47 @@
project(xtrxoutput)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(PLUGIN_PREFIX "../../../plugins/samplesink/xtrxoutput")
set(xtrxoutput_SOURCES
${PLUGIN_PREFIX}/xtrxoutput.cpp
${PLUGIN_PREFIX}/xtrxoutputplugin.cpp
${PLUGIN_PREFIX}/xtrxoutputsettings.cpp
${PLUGIN_PREFIX}/xtrxoutputthread.cpp
)
set(xtrxoutput_HEADERS
${PLUGIN_PREFIX}/xtrxoutput.h
${PLUGIN_PREFIX}/xtrxoutputplugin.h
${PLUGIN_PREFIX}/xtrxoutputsettings.h
${PLUGIN_PREFIX}/xtrxoutputthread.h
)
include_directories(
.
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
${CMAKE_SOURCE_DIR}/devices
${LIBXTRX_INCLUDE_DIRS}
)
add_definitions(${QT_DEFINITIONS})
add_definitions(-DQT_PLUGIN)
add_definitions(-DQT_SHARED)
add_library(outputxtrxsrv SHARED
${xtrxoutput_SOURCES}
${xtrxoutput_HEADERS_MOC}
)
target_link_libraries(outputxtrxsrv
${QT_LIBRARIES}
${LIBXTRX_LIBRARIES}
sdrbase
swagger
xtrxdevice
)
target_link_libraries(outputxtrxsrv Qt5::Core)
install(TARGETS outputxtrxsrv DESTINATION lib/pluginssrv/samplesink)

View File

@ -2182,6 +2182,9 @@ margin-bottom: 20px;
},
"xtrxInputReport" : {
"$ref" : "#/definitions/XtrxInputReport"
},
"xtrxOutputReport" : {
"$ref" : "#/definitions/XtrxOutputReport"
}
},
"description" : "Base device report. Only the device report corresponding to the device specified in the deviceHwType is or should be present."
@ -2309,6 +2312,9 @@ margin-bottom: 20px;
},
"xtrxInputSettings" : {
"$ref" : "#/definitions/XtrxInputSettings"
},
"xtrxOutputSettings" : {
"$ref" : "#/definitions/XtrxOutputSettings"
}
},
"description" : "Base device settings. Only the device settings corresponding to the device specified in the deviceHwType field is or should be present."
@ -4858,10 +4864,6 @@ margin-bottom: 20px;
"type" : "integer",
"description" : "1 if info was successfully retrieved else 0"
},
"streamActive" : {
"type" : "integer",
"description" : "1 if active else 0"
},
"fifoSize" : {
"type" : "integer"
},
@ -4968,6 +4970,92 @@ margin-bottom: 20px;
}
},
"description" : "XTRX"
};
defs.XtrxOutputReport = {
"properties" : {
"success" : {
"type" : "integer",
"description" : "1 if info was successfully retrieved else 0"
},
"fifoSize" : {
"type" : "integer"
},
"fifoFill" : {
"type" : "integer"
},
"temperature" : {
"type" : "number",
"format" : "float"
},
"gpsLock" : {
"type" : "integer",
"description" : "1 if GPSDO is locked else 0"
}
},
"description" : "XTRX"
};
defs.XtrxOutputSettings = {
"properties" : {
"centerFrequency" : {
"type" : "integer",
"format" : "int64"
},
"devSampleRate" : {
"type" : "integer"
},
"log2HardInterp" : {
"type" : "integer"
},
"log2SoftInterp" : {
"type" : "integer"
},
"lpfBW" : {
"type" : "integer",
"description" : "LMS analog lowpass filter bandwidth (Hz)"
},
"gain" : {
"type" : "integer",
"description" : "Optimally distributed gain (dB)"
},
"ncoEnable" : {
"type" : "integer",
"description" : "Enable TSP NCO and mixing (1 for yes, 0 for no)"
},
"ncoFrequency" : {
"type" : "integer",
"description" : "Frequency shift from LO"
},
"antennaPath" : {
"type" : "integer",
"description" : "Antenna selected (enum value from xtrx_antenna_t)"
},
"extClock" : {
"type" : "integer",
"description" : "Use external clock source (1 for yes, 0 for no)"
},
"extClockFreq" : {
"type" : "integer",
"description" : "Frequency (Hz) of external clock source"
},
"pwrmode" : {
"type" : "integer",
"description" : "LMS power mode (0 save max to 7 perf max)"
},
"useReverseAPI" : {
"type" : "integer",
"description" : "Synchronize with reverse API (1 for yes, 0 for no)"
},
"reverseAPIAddress" : {
"type" : "string"
},
"reverseAPIPort" : {
"type" : "integer"
},
"reverseAPIDeviceIndex" : {
"type" : "integer"
}
},
"description" : "XTRX"
};
</script>
@ -24000,7 +24088,7 @@ except ApiException as e:
</div>
<div id="generator">
<div class="content">
Generated 2019-01-01T11:45:52.860+01:00
Generated 2019-01-02T09:02:53.799+01:00
</div>
</div>
</div>

View File

@ -70,8 +70,68 @@ XtrxInputReport:
success:
description: 1 if info was successfully retrieved else 0
type: integer
streamActive:
description: 1 if active else 0
fifoSize:
type: integer
fifoFill:
type: integer
temperature:
type: number
format: float
gpsLock:
description: 1 if GPSDO is locked else 0
type: integer
XtrxOutputSettings:
description: XTRX
properties:
centerFrequency:
type: integer
format: int64
devSampleRate:
type: integer
log2HardInterp:
type: integer
log2SoftInterp:
type: integer
lpfBW:
description: LMS analog lowpass filter bandwidth (Hz)
type: integer
gain:
description: Optimally distributed gain (dB)
type: integer
ncoEnable:
description: Enable TSP NCO and mixing (1 for yes, 0 for no)
type: integer
ncoFrequency:
description: Frequency shift from LO
type: integer
antennaPath:
description: Antenna selected (enum value from xtrx_antenna_t)
type: integer
extClock:
description: Use external clock source (1 for yes, 0 for no)
type: integer
extClockFreq:
description: Frequency (Hz) of external clock source
type: integer
pwrmode:
description: LMS power mode (0 save max to 7 perf max)
type: integer
useReverseAPI:
description: Synchronize with reverse API (1 for yes, 0 for no)
type: integer
reverseAPIAddress:
type: string
reverseAPIPort:
type: integer
reverseAPIDeviceIndex:
type: integer
XtrxOutputReport:
description: XTRX
properties:
success:
description: 1 if info was successfully retrieved else 0
type: integer
fifoSize:
type: integer
@ -82,4 +142,4 @@ XtrxInputReport:
format: float
gpsLock:
description: 1 if GPSDO is locked else 0
type: integer
type: integer

View File

@ -1807,6 +1807,8 @@ definitions:
$ref: "/doc/swagger/include/TestSource.yaml#/TestSourceSettings"
xtrxInputSettings:
$ref: "/doc/swagger/include/Xtrx.yaml#/XtrxInputSettings"
xtrxOutputSettings:
$ref: "/doc/swagger/include/Xtrx.yaml#/XtrxOutputSettings"
DeviceReport:
@ -1856,6 +1858,8 @@ definitions:
$ref: "/doc/swagger/include/SoapySDR.yaml#/SoapySDRReport"
xtrxInputReport:
$ref: "/doc/swagger/include/Xtrx.yaml#/XtrxInputReport"
xtrxOutputReport:
$ref: "/doc/swagger/include/Xtrx.yaml#/XtrxOutputReport"
ChannelSettings:
description: Base channel settings. Only the channel settings corresponding to the channel specified in the channelType field is or should be present.

View File

@ -79,4 +79,67 @@ XtrxInputReport:
format: float
gpsLock:
description: 1 if GPSDO is locked else 0
type: integer
type: integer
XtrxOutputSettings:
description: XTRX
properties:
centerFrequency:
type: integer
format: int64
devSampleRate:
type: integer
log2HardInterp:
type: integer
log2SoftInterp:
type: integer
lpfBW:
description: LMS analog lowpass filter bandwidth (Hz)
type: integer
gain:
description: Optimally distributed gain (dB)
type: integer
ncoEnable:
description: Enable TSP NCO and mixing (1 for yes, 0 for no)
type: integer
ncoFrequency:
description: Frequency shift from LO
type: integer
antennaPath:
description: Antenna selected (enum value from xtrx_antenna_t)
type: integer
extClock:
description: Use external clock source (1 for yes, 0 for no)
type: integer
extClockFreq:
description: Frequency (Hz) of external clock source
type: integer
pwrmode:
description: LMS power mode (0 save max to 7 perf max)
type: integer
useReverseAPI:
description: Synchronize with reverse API (1 for yes, 0 for no)
type: integer
reverseAPIAddress:
type: string
reverseAPIPort:
type: integer
reverseAPIDeviceIndex:
type: integer
XtrxOutputReport:
description: XTRX
properties:
success:
description: 1 if info was successfully retrieved else 0
type: integer
fifoSize:
type: integer
fifoFill:
type: integer
temperature:
type: number
format: float
gpsLock:
description: 1 if GPSDO is locked else 0
type: integer

View File

@ -1807,6 +1807,8 @@ definitions:
$ref: "http://localhost:8081/api/swagger/include/TestSource.yaml#/TestSourceSettings"
xtrxInputSettings:
$ref: "http://localhost:8081/api/swagger/include/Xtrx.yaml#/XtrxInputSettings"
xtrxOutputSettings:
$ref: "http://localhost:8081/api/swagger/include/Xtrx.yaml#/XtrxOutputSettings"
DeviceReport:
@ -1856,6 +1858,8 @@ definitions:
$ref: "http://localhost:8081/api/swagger/include/SoapySDR.yaml#/SoapySDRReport"
xtrxInputReport:
$ref: "http://localhost:8081/api/swagger/include/Xtrx.yaml#/XtrxInputReport"
xtrxOutputReport:
$ref: "http://localhost:8081/api/swagger/include/Xtrx.yaml#/XtrxOutputReport"
ChannelSettings:
description: Base channel settings. Only the channel settings corresponding to the channel specified in the channelType field is or should be present.

View File

@ -2182,6 +2182,9 @@ margin-bottom: 20px;
},
"xtrxInputReport" : {
"$ref" : "#/definitions/XtrxInputReport"
},
"xtrxOutputReport" : {
"$ref" : "#/definitions/XtrxOutputReport"
}
},
"description" : "Base device report. Only the device report corresponding to the device specified in the deviceHwType is or should be present."
@ -2309,6 +2312,9 @@ margin-bottom: 20px;
},
"xtrxInputSettings" : {
"$ref" : "#/definitions/XtrxInputSettings"
},
"xtrxOutputSettings" : {
"$ref" : "#/definitions/XtrxOutputSettings"
}
},
"description" : "Base device settings. Only the device settings corresponding to the device specified in the deviceHwType field is or should be present."
@ -4858,10 +4864,6 @@ margin-bottom: 20px;
"type" : "integer",
"description" : "1 if info was successfully retrieved else 0"
},
"streamActive" : {
"type" : "integer",
"description" : "1 if active else 0"
},
"fifoSize" : {
"type" : "integer"
},
@ -4968,6 +4970,92 @@ margin-bottom: 20px;
}
},
"description" : "XTRX"
};
defs.XtrxOutputReport = {
"properties" : {
"success" : {
"type" : "integer",
"description" : "1 if info was successfully retrieved else 0"
},
"fifoSize" : {
"type" : "integer"
},
"fifoFill" : {
"type" : "integer"
},
"temperature" : {
"type" : "number",
"format" : "float"
},
"gpsLock" : {
"type" : "integer",
"description" : "1 if GPSDO is locked else 0"
}
},
"description" : "XTRX"
};
defs.XtrxOutputSettings = {
"properties" : {
"centerFrequency" : {
"type" : "integer",
"format" : "int64"
},
"devSampleRate" : {
"type" : "integer"
},
"log2HardInterp" : {
"type" : "integer"
},
"log2SoftInterp" : {
"type" : "integer"
},
"lpfBW" : {
"type" : "integer",
"description" : "LMS analog lowpass filter bandwidth (Hz)"
},
"gain" : {
"type" : "integer",
"description" : "Optimally distributed gain (dB)"
},
"ncoEnable" : {
"type" : "integer",
"description" : "Enable TSP NCO and mixing (1 for yes, 0 for no)"
},
"ncoFrequency" : {
"type" : "integer",
"description" : "Frequency shift from LO"
},
"antennaPath" : {
"type" : "integer",
"description" : "Antenna selected (enum value from xtrx_antenna_t)"
},
"extClock" : {
"type" : "integer",
"description" : "Use external clock source (1 for yes, 0 for no)"
},
"extClockFreq" : {
"type" : "integer",
"description" : "Frequency (Hz) of external clock source"
},
"pwrmode" : {
"type" : "integer",
"description" : "LMS power mode (0 save max to 7 perf max)"
},
"useReverseAPI" : {
"type" : "integer",
"description" : "Synchronize with reverse API (1 for yes, 0 for no)"
},
"reverseAPIAddress" : {
"type" : "string"
},
"reverseAPIPort" : {
"type" : "integer"
},
"reverseAPIDeviceIndex" : {
"type" : "integer"
}
},
"description" : "XTRX"
};
</script>
@ -24000,7 +24088,7 @@ except ApiException as e:
</div>
<div id="generator">
<div class="content">
Generated 2019-01-01T11:45:52.860+01:00
Generated 2019-01-02T09:02:53.799+01:00
</div>
</div>
</div>

View File

@ -66,6 +66,8 @@ SWGDeviceReport::SWGDeviceReport() {
m_soapy_sdr_output_report_isSet = false;
xtrx_input_report = nullptr;
m_xtrx_input_report_isSet = false;
xtrx_output_report = nullptr;
m_xtrx_output_report_isSet = false;
}
SWGDeviceReport::~SWGDeviceReport() {
@ -112,6 +114,8 @@ SWGDeviceReport::init() {
m_soapy_sdr_output_report_isSet = false;
xtrx_input_report = new SWGXtrxInputReport();
m_xtrx_input_report_isSet = false;
xtrx_output_report = new SWGXtrxOutputReport();
m_xtrx_output_report_isSet = false;
}
void
@ -171,6 +175,9 @@ SWGDeviceReport::cleanup() {
if(xtrx_input_report != nullptr) {
delete xtrx_input_report;
}
if(xtrx_output_report != nullptr) {
delete xtrx_output_report;
}
}
SWGDeviceReport*
@ -222,6 +229,8 @@ SWGDeviceReport::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&xtrx_input_report, pJson["xtrxInputReport"], "SWGXtrxInputReport", "SWGXtrxInputReport");
::SWGSDRangel::setValue(&xtrx_output_report, pJson["xtrxOutputReport"], "SWGXtrxOutputReport", "SWGXtrxOutputReport");
}
QString
@ -295,6 +304,9 @@ SWGDeviceReport::asJsonObject() {
if((xtrx_input_report != nullptr) && (xtrx_input_report->isSet())){
toJsonValue(QString("xtrxInputReport"), xtrx_input_report, obj, QString("SWGXtrxInputReport"));
}
if((xtrx_output_report != nullptr) && (xtrx_output_report->isSet())){
toJsonValue(QString("xtrxOutputReport"), xtrx_output_report, obj, QString("SWGXtrxOutputReport"));
}
return obj;
}
@ -489,6 +501,16 @@ SWGDeviceReport::setXtrxInputReport(SWGXtrxInputReport* xtrx_input_report) {
this->m_xtrx_input_report_isSet = true;
}
SWGXtrxOutputReport*
SWGDeviceReport::getXtrxOutputReport() {
return xtrx_output_report;
}
void
SWGDeviceReport::setXtrxOutputReport(SWGXtrxOutputReport* xtrx_output_report) {
this->xtrx_output_report = xtrx_output_report;
this->m_xtrx_output_report_isSet = true;
}
bool
SWGDeviceReport::isSet(){
@ -513,6 +535,7 @@ SWGDeviceReport::isSet(){
if(soapy_sdr_input_report != nullptr && soapy_sdr_input_report->isSet()){ isObjectUpdated = true; break;}
if(soapy_sdr_output_report != nullptr && soapy_sdr_output_report->isSet()){ isObjectUpdated = true; break;}
if(xtrx_input_report != nullptr && xtrx_input_report->isSet()){ isObjectUpdated = true; break;}
if(xtrx_output_report != nullptr && xtrx_output_report->isSet()){ isObjectUpdated = true; break;}
}while(false);
return isObjectUpdated;
}

View File

@ -38,6 +38,7 @@
#include "SWGSDRdaemonSourceReport.h"
#include "SWGSoapySDRReport.h"
#include "SWGXtrxInputReport.h"
#include "SWGXtrxOutputReport.h"
#include <QString>
#include "SWGObject.h"
@ -115,6 +116,9 @@ public:
SWGXtrxInputReport* getXtrxInputReport();
void setXtrxInputReport(SWGXtrxInputReport* xtrx_input_report);
SWGXtrxOutputReport* getXtrxOutputReport();
void setXtrxOutputReport(SWGXtrxOutputReport* xtrx_output_report);
virtual bool isSet() override;
@ -176,6 +180,9 @@ private:
SWGXtrxInputReport* xtrx_input_report;
bool m_xtrx_input_report_isSet;
SWGXtrxOutputReport* xtrx_output_report;
bool m_xtrx_output_report_isSet;
};
}

View File

@ -80,6 +80,8 @@ SWGDeviceSettings::SWGDeviceSettings() {
m_test_source_settings_isSet = false;
xtrx_input_settings = nullptr;
m_xtrx_input_settings_isSet = false;
xtrx_output_settings = nullptr;
m_xtrx_output_settings_isSet = false;
}
SWGDeviceSettings::~SWGDeviceSettings() {
@ -140,6 +142,8 @@ SWGDeviceSettings::init() {
m_test_source_settings_isSet = false;
xtrx_input_settings = new SWGXtrxInputSettings();
m_xtrx_input_settings_isSet = false;
xtrx_output_settings = new SWGXtrxOutputSettings();
m_xtrx_output_settings_isSet = false;
}
void
@ -220,6 +224,9 @@ SWGDeviceSettings::cleanup() {
if(xtrx_input_settings != nullptr) {
delete xtrx_input_settings;
}
if(xtrx_output_settings != nullptr) {
delete xtrx_output_settings;
}
}
SWGDeviceSettings*
@ -285,6 +292,8 @@ SWGDeviceSettings::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&xtrx_input_settings, pJson["xtrxInputSettings"], "SWGXtrxInputSettings", "SWGXtrxInputSettings");
::SWGSDRangel::setValue(&xtrx_output_settings, pJson["xtrxOutputSettings"], "SWGXtrxOutputSettings", "SWGXtrxOutputSettings");
}
QString
@ -379,6 +388,9 @@ SWGDeviceSettings::asJsonObject() {
if((xtrx_input_settings != nullptr) && (xtrx_input_settings->isSet())){
toJsonValue(QString("xtrxInputSettings"), xtrx_input_settings, obj, QString("SWGXtrxInputSettings"));
}
if((xtrx_output_settings != nullptr) && (xtrx_output_settings->isSet())){
toJsonValue(QString("xtrxOutputSettings"), xtrx_output_settings, obj, QString("SWGXtrxOutputSettings"));
}
return obj;
}
@ -643,6 +655,16 @@ SWGDeviceSettings::setXtrxInputSettings(SWGXtrxInputSettings* xtrx_input_setting
this->m_xtrx_input_settings_isSet = true;
}
SWGXtrxOutputSettings*
SWGDeviceSettings::getXtrxOutputSettings() {
return xtrx_output_settings;
}
void
SWGDeviceSettings::setXtrxOutputSettings(SWGXtrxOutputSettings* xtrx_output_settings) {
this->xtrx_output_settings = xtrx_output_settings;
this->m_xtrx_output_settings_isSet = true;
}
bool
SWGDeviceSettings::isSet(){
@ -674,6 +696,7 @@ SWGDeviceSettings::isSet(){
if(soapy_sdr_output_settings != nullptr && soapy_sdr_output_settings->isSet()){ isObjectUpdated = true; break;}
if(test_source_settings != nullptr && test_source_settings->isSet()){ isObjectUpdated = true; break;}
if(xtrx_input_settings != nullptr && xtrx_input_settings->isSet()){ isObjectUpdated = true; break;}
if(xtrx_output_settings != nullptr && xtrx_output_settings->isSet()){ isObjectUpdated = true; break;}
}while(false);
return isObjectUpdated;
}

View File

@ -46,6 +46,7 @@
#include "SWGSoapySDROutputSettings.h"
#include "SWGTestSourceSettings.h"
#include "SWGXtrxInputSettings.h"
#include "SWGXtrxOutputSettings.h"
#include <QString>
#include "SWGObject.h"
@ -144,6 +145,9 @@ public:
SWGXtrxInputSettings* getXtrxInputSettings();
void setXtrxInputSettings(SWGXtrxInputSettings* xtrx_input_settings);
SWGXtrxOutputSettings* getXtrxOutputSettings();
void setXtrxOutputSettings(SWGXtrxOutputSettings* xtrx_output_settings);
virtual bool isSet() override;
@ -226,6 +230,9 @@ private:
SWGXtrxInputSettings* xtrx_input_settings;
bool m_xtrx_input_settings_isSet;
SWGXtrxOutputSettings* xtrx_output_settings;
bool m_xtrx_output_settings_isSet;
};
}

View File

@ -131,6 +131,8 @@
#include "SWGWFMModSettings.h"
#include "SWGXtrxInputReport.h"
#include "SWGXtrxInputSettings.h"
#include "SWGXtrxOutputReport.h"
#include "SWGXtrxOutputSettings.h"
namespace SWGSDRangel {
@ -486,6 +488,12 @@ namespace SWGSDRangel {
if(QString("SWGXtrxInputSettings").compare(type) == 0) {
return new SWGXtrxInputSettings();
}
if(QString("SWGXtrxOutputReport").compare(type) == 0) {
return new SWGXtrxOutputReport();
}
if(QString("SWGXtrxOutputSettings").compare(type) == 0) {
return new SWGXtrxOutputSettings();
}
return nullptr;
}

View File

@ -30,8 +30,6 @@ SWGXtrxInputReport::SWGXtrxInputReport(QString* json) {
SWGXtrxInputReport::SWGXtrxInputReport() {
success = 0;
m_success_isSet = false;
stream_active = 0;
m_stream_active_isSet = false;
fifo_size = 0;
m_fifo_size_isSet = false;
fifo_fill = 0;
@ -50,8 +48,6 @@ void
SWGXtrxInputReport::init() {
success = 0;
m_success_isSet = false;
stream_active = 0;
m_stream_active_isSet = false;
fifo_size = 0;
m_fifo_size_isSet = false;
fifo_fill = 0;
@ -69,7 +65,6 @@ SWGXtrxInputReport::cleanup() {
}
SWGXtrxInputReport*
@ -85,8 +80,6 @@ void
SWGXtrxInputReport::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&success, pJson["success"], "qint32", "");
::SWGSDRangel::setValue(&stream_active, pJson["streamActive"], "qint32", "");
::SWGSDRangel::setValue(&fifo_size, pJson["fifoSize"], "qint32", "");
::SWGSDRangel::setValue(&fifo_fill, pJson["fifoFill"], "qint32", "");
@ -114,9 +107,6 @@ SWGXtrxInputReport::asJsonObject() {
if(m_success_isSet){
obj->insert("success", QJsonValue(success));
}
if(m_stream_active_isSet){
obj->insert("streamActive", QJsonValue(stream_active));
}
if(m_fifo_size_isSet){
obj->insert("fifoSize", QJsonValue(fifo_size));
}
@ -143,16 +133,6 @@ SWGXtrxInputReport::setSuccess(qint32 success) {
this->m_success_isSet = true;
}
qint32
SWGXtrxInputReport::getStreamActive() {
return stream_active;
}
void
SWGXtrxInputReport::setStreamActive(qint32 stream_active) {
this->stream_active = stream_active;
this->m_stream_active_isSet = true;
}
qint32
SWGXtrxInputReport::getFifoSize() {
return fifo_size;
@ -199,7 +179,6 @@ SWGXtrxInputReport::isSet(){
bool isObjectUpdated = false;
do{
if(m_success_isSet){ isObjectUpdated = true; break;}
if(m_stream_active_isSet){ isObjectUpdated = true; break;}
if(m_fifo_size_isSet){ isObjectUpdated = true; break;}
if(m_fifo_fill_isSet){ isObjectUpdated = true; break;}
if(m_temperature_isSet){ isObjectUpdated = true; break;}

View File

@ -44,9 +44,6 @@ public:
qint32 getSuccess();
void setSuccess(qint32 success);
qint32 getStreamActive();
void setStreamActive(qint32 stream_active);
qint32 getFifoSize();
void setFifoSize(qint32 fifo_size);
@ -66,9 +63,6 @@ private:
qint32 success;
bool m_success_isSet;
qint32 stream_active;
bool m_stream_active_isSet;
qint32 fifo_size;
bool m_fifo_size_isSet;

View File

@ -0,0 +1,190 @@
/**
* SDRangel
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
*
* OpenAPI spec version: 4.4.0
* Contact: f4exb06@gmail.com
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
#include "SWGXtrxOutputReport.h"
#include "SWGHelpers.h"
#include <QJsonDocument>
#include <QJsonArray>
#include <QObject>
#include <QDebug>
namespace SWGSDRangel {
SWGXtrxOutputReport::SWGXtrxOutputReport(QString* json) {
init();
this->fromJson(*json);
}
SWGXtrxOutputReport::SWGXtrxOutputReport() {
success = 0;
m_success_isSet = false;
fifo_size = 0;
m_fifo_size_isSet = false;
fifo_fill = 0;
m_fifo_fill_isSet = false;
temperature = 0.0f;
m_temperature_isSet = false;
gps_lock = 0;
m_gps_lock_isSet = false;
}
SWGXtrxOutputReport::~SWGXtrxOutputReport() {
this->cleanup();
}
void
SWGXtrxOutputReport::init() {
success = 0;
m_success_isSet = false;
fifo_size = 0;
m_fifo_size_isSet = false;
fifo_fill = 0;
m_fifo_fill_isSet = false;
temperature = 0.0f;
m_temperature_isSet = false;
gps_lock = 0;
m_gps_lock_isSet = false;
}
void
SWGXtrxOutputReport::cleanup() {
}
SWGXtrxOutputReport*
SWGXtrxOutputReport::fromJson(QString &json) {
QByteArray array (json.toStdString().c_str());
QJsonDocument doc = QJsonDocument::fromJson(array);
QJsonObject jsonObject = doc.object();
this->fromJsonObject(jsonObject);
return this;
}
void
SWGXtrxOutputReport::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&success, pJson["success"], "qint32", "");
::SWGSDRangel::setValue(&fifo_size, pJson["fifoSize"], "qint32", "");
::SWGSDRangel::setValue(&fifo_fill, pJson["fifoFill"], "qint32", "");
::SWGSDRangel::setValue(&temperature, pJson["temperature"], "float", "");
::SWGSDRangel::setValue(&gps_lock, pJson["gpsLock"], "qint32", "");
}
QString
SWGXtrxOutputReport::asJson ()
{
QJsonObject* obj = this->asJsonObject();
QJsonDocument doc(*obj);
QByteArray bytes = doc.toJson();
delete obj;
return QString(bytes);
}
QJsonObject*
SWGXtrxOutputReport::asJsonObject() {
QJsonObject* obj = new QJsonObject();
if(m_success_isSet){
obj->insert("success", QJsonValue(success));
}
if(m_fifo_size_isSet){
obj->insert("fifoSize", QJsonValue(fifo_size));
}
if(m_fifo_fill_isSet){
obj->insert("fifoFill", QJsonValue(fifo_fill));
}
if(m_temperature_isSet){
obj->insert("temperature", QJsonValue(temperature));
}
if(m_gps_lock_isSet){
obj->insert("gpsLock", QJsonValue(gps_lock));
}
return obj;
}
qint32
SWGXtrxOutputReport::getSuccess() {
return success;
}
void
SWGXtrxOutputReport::setSuccess(qint32 success) {
this->success = success;
this->m_success_isSet = true;
}
qint32
SWGXtrxOutputReport::getFifoSize() {
return fifo_size;
}
void
SWGXtrxOutputReport::setFifoSize(qint32 fifo_size) {
this->fifo_size = fifo_size;
this->m_fifo_size_isSet = true;
}
qint32
SWGXtrxOutputReport::getFifoFill() {
return fifo_fill;
}
void
SWGXtrxOutputReport::setFifoFill(qint32 fifo_fill) {
this->fifo_fill = fifo_fill;
this->m_fifo_fill_isSet = true;
}
float
SWGXtrxOutputReport::getTemperature() {
return temperature;
}
void
SWGXtrxOutputReport::setTemperature(float temperature) {
this->temperature = temperature;
this->m_temperature_isSet = true;
}
qint32
SWGXtrxOutputReport::getGpsLock() {
return gps_lock;
}
void
SWGXtrxOutputReport::setGpsLock(qint32 gps_lock) {
this->gps_lock = gps_lock;
this->m_gps_lock_isSet = true;
}
bool
SWGXtrxOutputReport::isSet(){
bool isObjectUpdated = false;
do{
if(m_success_isSet){ isObjectUpdated = true; break;}
if(m_fifo_size_isSet){ isObjectUpdated = true; break;}
if(m_fifo_fill_isSet){ isObjectUpdated = true; break;}
if(m_temperature_isSet){ isObjectUpdated = true; break;}
if(m_gps_lock_isSet){ isObjectUpdated = true; break;}
}while(false);
return isObjectUpdated;
}
}

View File

@ -0,0 +1,82 @@
/**
* SDRangel
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
*
* OpenAPI spec version: 4.4.0
* Contact: f4exb06@gmail.com
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/*
* SWGXtrxOutputReport.h
*
* XTRX
*/
#ifndef SWGXtrxOutputReport_H_
#define SWGXtrxOutputReport_H_
#include <QJsonObject>
#include "SWGObject.h"
#include "export.h"
namespace SWGSDRangel {
class SWG_API SWGXtrxOutputReport: public SWGObject {
public:
SWGXtrxOutputReport();
SWGXtrxOutputReport(QString* json);
virtual ~SWGXtrxOutputReport();
void init();
void cleanup();
virtual QString asJson () override;
virtual QJsonObject* asJsonObject() override;
virtual void fromJsonObject(QJsonObject &json) override;
virtual SWGXtrxOutputReport* fromJson(QString &jsonString) override;
qint32 getSuccess();
void setSuccess(qint32 success);
qint32 getFifoSize();
void setFifoSize(qint32 fifo_size);
qint32 getFifoFill();
void setFifoFill(qint32 fifo_fill);
float getTemperature();
void setTemperature(float temperature);
qint32 getGpsLock();
void setGpsLock(qint32 gps_lock);
virtual bool isSet() override;
private:
qint32 success;
bool m_success_isSet;
qint32 fifo_size;
bool m_fifo_size_isSet;
qint32 fifo_fill;
bool m_fifo_fill_isSet;
float temperature;
bool m_temperature_isSet;
qint32 gps_lock;
bool m_gps_lock_isSet;
};
}
#endif /* SWGXtrxOutputReport_H_ */

View File

@ -0,0 +1,423 @@
/**
* SDRangel
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
*
* OpenAPI spec version: 4.4.0
* Contact: f4exb06@gmail.com
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
#include "SWGXtrxOutputSettings.h"
#include "SWGHelpers.h"
#include <QJsonDocument>
#include <QJsonArray>
#include <QObject>
#include <QDebug>
namespace SWGSDRangel {
SWGXtrxOutputSettings::SWGXtrxOutputSettings(QString* json) {
init();
this->fromJson(*json);
}
SWGXtrxOutputSettings::SWGXtrxOutputSettings() {
center_frequency = 0L;
m_center_frequency_isSet = false;
dev_sample_rate = 0;
m_dev_sample_rate_isSet = false;
log2_hard_interp = 0;
m_log2_hard_interp_isSet = false;
log2_soft_interp = 0;
m_log2_soft_interp_isSet = false;
lpf_bw = 0;
m_lpf_bw_isSet = false;
gain = 0;
m_gain_isSet = false;
nco_enable = 0;
m_nco_enable_isSet = false;
nco_frequency = 0;
m_nco_frequency_isSet = false;
antenna_path = 0;
m_antenna_path_isSet = false;
ext_clock = 0;
m_ext_clock_isSet = false;
ext_clock_freq = 0;
m_ext_clock_freq_isSet = false;
pwrmode = 0;
m_pwrmode_isSet = false;
use_reverse_api = 0;
m_use_reverse_api_isSet = false;
reverse_api_address = nullptr;
m_reverse_api_address_isSet = false;
reverse_api_port = 0;
m_reverse_api_port_isSet = false;
reverse_api_device_index = 0;
m_reverse_api_device_index_isSet = false;
}
SWGXtrxOutputSettings::~SWGXtrxOutputSettings() {
this->cleanup();
}
void
SWGXtrxOutputSettings::init() {
center_frequency = 0L;
m_center_frequency_isSet = false;
dev_sample_rate = 0;
m_dev_sample_rate_isSet = false;
log2_hard_interp = 0;
m_log2_hard_interp_isSet = false;
log2_soft_interp = 0;
m_log2_soft_interp_isSet = false;
lpf_bw = 0;
m_lpf_bw_isSet = false;
gain = 0;
m_gain_isSet = false;
nco_enable = 0;
m_nco_enable_isSet = false;
nco_frequency = 0;
m_nco_frequency_isSet = false;
antenna_path = 0;
m_antenna_path_isSet = false;
ext_clock = 0;
m_ext_clock_isSet = false;
ext_clock_freq = 0;
m_ext_clock_freq_isSet = false;
pwrmode = 0;
m_pwrmode_isSet = false;
use_reverse_api = 0;
m_use_reverse_api_isSet = false;
reverse_api_address = new QString("");
m_reverse_api_address_isSet = false;
reverse_api_port = 0;
m_reverse_api_port_isSet = false;
reverse_api_device_index = 0;
m_reverse_api_device_index_isSet = false;
}
void
SWGXtrxOutputSettings::cleanup() {
if(reverse_api_address != nullptr) {
delete reverse_api_address;
}
}
SWGXtrxOutputSettings*
SWGXtrxOutputSettings::fromJson(QString &json) {
QByteArray array (json.toStdString().c_str());
QJsonDocument doc = QJsonDocument::fromJson(array);
QJsonObject jsonObject = doc.object();
this->fromJsonObject(jsonObject);
return this;
}
void
SWGXtrxOutputSettings::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&center_frequency, pJson["centerFrequency"], "qint64", "");
::SWGSDRangel::setValue(&dev_sample_rate, pJson["devSampleRate"], "qint32", "");
::SWGSDRangel::setValue(&log2_hard_interp, pJson["log2HardInterp"], "qint32", "");
::SWGSDRangel::setValue(&log2_soft_interp, pJson["log2SoftInterp"], "qint32", "");
::SWGSDRangel::setValue(&lpf_bw, pJson["lpfBW"], "qint32", "");
::SWGSDRangel::setValue(&gain, pJson["gain"], "qint32", "");
::SWGSDRangel::setValue(&nco_enable, pJson["ncoEnable"], "qint32", "");
::SWGSDRangel::setValue(&nco_frequency, pJson["ncoFrequency"], "qint32", "");
::SWGSDRangel::setValue(&antenna_path, pJson["antennaPath"], "qint32", "");
::SWGSDRangel::setValue(&ext_clock, pJson["extClock"], "qint32", "");
::SWGSDRangel::setValue(&ext_clock_freq, pJson["extClockFreq"], "qint32", "");
::SWGSDRangel::setValue(&pwrmode, pJson["pwrmode"], "qint32", "");
::SWGSDRangel::setValue(&use_reverse_api, pJson["useReverseAPI"], "qint32", "");
::SWGSDRangel::setValue(&reverse_api_address, pJson["reverseAPIAddress"], "QString", "QString");
::SWGSDRangel::setValue(&reverse_api_port, pJson["reverseAPIPort"], "qint32", "");
::SWGSDRangel::setValue(&reverse_api_device_index, pJson["reverseAPIDeviceIndex"], "qint32", "");
}
QString
SWGXtrxOutputSettings::asJson ()
{
QJsonObject* obj = this->asJsonObject();
QJsonDocument doc(*obj);
QByteArray bytes = doc.toJson();
delete obj;
return QString(bytes);
}
QJsonObject*
SWGXtrxOutputSettings::asJsonObject() {
QJsonObject* obj = new QJsonObject();
if(m_center_frequency_isSet){
obj->insert("centerFrequency", QJsonValue(center_frequency));
}
if(m_dev_sample_rate_isSet){
obj->insert("devSampleRate", QJsonValue(dev_sample_rate));
}
if(m_log2_hard_interp_isSet){
obj->insert("log2HardInterp", QJsonValue(log2_hard_interp));
}
if(m_log2_soft_interp_isSet){
obj->insert("log2SoftInterp", QJsonValue(log2_soft_interp));
}
if(m_lpf_bw_isSet){
obj->insert("lpfBW", QJsonValue(lpf_bw));
}
if(m_gain_isSet){
obj->insert("gain", QJsonValue(gain));
}
if(m_nco_enable_isSet){
obj->insert("ncoEnable", QJsonValue(nco_enable));
}
if(m_nco_frequency_isSet){
obj->insert("ncoFrequency", QJsonValue(nco_frequency));
}
if(m_antenna_path_isSet){
obj->insert("antennaPath", QJsonValue(antenna_path));
}
if(m_ext_clock_isSet){
obj->insert("extClock", QJsonValue(ext_clock));
}
if(m_ext_clock_freq_isSet){
obj->insert("extClockFreq", QJsonValue(ext_clock_freq));
}
if(m_pwrmode_isSet){
obj->insert("pwrmode", QJsonValue(pwrmode));
}
if(m_use_reverse_api_isSet){
obj->insert("useReverseAPI", QJsonValue(use_reverse_api));
}
if(reverse_api_address != nullptr && *reverse_api_address != QString("")){
toJsonValue(QString("reverseAPIAddress"), reverse_api_address, obj, QString("QString"));
}
if(m_reverse_api_port_isSet){
obj->insert("reverseAPIPort", QJsonValue(reverse_api_port));
}
if(m_reverse_api_device_index_isSet){
obj->insert("reverseAPIDeviceIndex", QJsonValue(reverse_api_device_index));
}
return obj;
}
qint64
SWGXtrxOutputSettings::getCenterFrequency() {
return center_frequency;
}
void
SWGXtrxOutputSettings::setCenterFrequency(qint64 center_frequency) {
this->center_frequency = center_frequency;
this->m_center_frequency_isSet = true;
}
qint32
SWGXtrxOutputSettings::getDevSampleRate() {
return dev_sample_rate;
}
void
SWGXtrxOutputSettings::setDevSampleRate(qint32 dev_sample_rate) {
this->dev_sample_rate = dev_sample_rate;
this->m_dev_sample_rate_isSet = true;
}
qint32
SWGXtrxOutputSettings::getLog2HardInterp() {
return log2_hard_interp;
}
void
SWGXtrxOutputSettings::setLog2HardInterp(qint32 log2_hard_interp) {
this->log2_hard_interp = log2_hard_interp;
this->m_log2_hard_interp_isSet = true;
}
qint32
SWGXtrxOutputSettings::getLog2SoftInterp() {
return log2_soft_interp;
}
void
SWGXtrxOutputSettings::setLog2SoftInterp(qint32 log2_soft_interp) {
this->log2_soft_interp = log2_soft_interp;
this->m_log2_soft_interp_isSet = true;
}
qint32
SWGXtrxOutputSettings::getLpfBw() {
return lpf_bw;
}
void
SWGXtrxOutputSettings::setLpfBw(qint32 lpf_bw) {
this->lpf_bw = lpf_bw;
this->m_lpf_bw_isSet = true;
}
qint32
SWGXtrxOutputSettings::getGain() {
return gain;
}
void
SWGXtrxOutputSettings::setGain(qint32 gain) {
this->gain = gain;
this->m_gain_isSet = true;
}
qint32
SWGXtrxOutputSettings::getNcoEnable() {
return nco_enable;
}
void
SWGXtrxOutputSettings::setNcoEnable(qint32 nco_enable) {
this->nco_enable = nco_enable;
this->m_nco_enable_isSet = true;
}
qint32
SWGXtrxOutputSettings::getNcoFrequency() {
return nco_frequency;
}
void
SWGXtrxOutputSettings::setNcoFrequency(qint32 nco_frequency) {
this->nco_frequency = nco_frequency;
this->m_nco_frequency_isSet = true;
}
qint32
SWGXtrxOutputSettings::getAntennaPath() {
return antenna_path;
}
void
SWGXtrxOutputSettings::setAntennaPath(qint32 antenna_path) {
this->antenna_path = antenna_path;
this->m_antenna_path_isSet = true;
}
qint32
SWGXtrxOutputSettings::getExtClock() {
return ext_clock;
}
void
SWGXtrxOutputSettings::setExtClock(qint32 ext_clock) {
this->ext_clock = ext_clock;
this->m_ext_clock_isSet = true;
}
qint32
SWGXtrxOutputSettings::getExtClockFreq() {
return ext_clock_freq;
}
void
SWGXtrxOutputSettings::setExtClockFreq(qint32 ext_clock_freq) {
this->ext_clock_freq = ext_clock_freq;
this->m_ext_clock_freq_isSet = true;
}
qint32
SWGXtrxOutputSettings::getPwrmode() {
return pwrmode;
}
void
SWGXtrxOutputSettings::setPwrmode(qint32 pwrmode) {
this->pwrmode = pwrmode;
this->m_pwrmode_isSet = true;
}
qint32
SWGXtrxOutputSettings::getUseReverseApi() {
return use_reverse_api;
}
void
SWGXtrxOutputSettings::setUseReverseApi(qint32 use_reverse_api) {
this->use_reverse_api = use_reverse_api;
this->m_use_reverse_api_isSet = true;
}
QString*
SWGXtrxOutputSettings::getReverseApiAddress() {
return reverse_api_address;
}
void
SWGXtrxOutputSettings::setReverseApiAddress(QString* reverse_api_address) {
this->reverse_api_address = reverse_api_address;
this->m_reverse_api_address_isSet = true;
}
qint32
SWGXtrxOutputSettings::getReverseApiPort() {
return reverse_api_port;
}
void
SWGXtrxOutputSettings::setReverseApiPort(qint32 reverse_api_port) {
this->reverse_api_port = reverse_api_port;
this->m_reverse_api_port_isSet = true;
}
qint32
SWGXtrxOutputSettings::getReverseApiDeviceIndex() {
return reverse_api_device_index;
}
void
SWGXtrxOutputSettings::setReverseApiDeviceIndex(qint32 reverse_api_device_index) {
this->reverse_api_device_index = reverse_api_device_index;
this->m_reverse_api_device_index_isSet = true;
}
bool
SWGXtrxOutputSettings::isSet(){
bool isObjectUpdated = false;
do{
if(m_center_frequency_isSet){ isObjectUpdated = true; break;}
if(m_dev_sample_rate_isSet){ isObjectUpdated = true; break;}
if(m_log2_hard_interp_isSet){ isObjectUpdated = true; break;}
if(m_log2_soft_interp_isSet){ isObjectUpdated = true; break;}
if(m_lpf_bw_isSet){ isObjectUpdated = true; break;}
if(m_gain_isSet){ isObjectUpdated = true; break;}
if(m_nco_enable_isSet){ isObjectUpdated = true; break;}
if(m_nco_frequency_isSet){ isObjectUpdated = true; break;}
if(m_antenna_path_isSet){ isObjectUpdated = true; break;}
if(m_ext_clock_isSet){ isObjectUpdated = true; break;}
if(m_ext_clock_freq_isSet){ isObjectUpdated = true; break;}
if(m_pwrmode_isSet){ isObjectUpdated = true; break;}
if(m_use_reverse_api_isSet){ isObjectUpdated = true; break;}
if(reverse_api_address != nullptr && *reverse_api_address != QString("")){ isObjectUpdated = true; break;}
if(m_reverse_api_port_isSet){ isObjectUpdated = true; break;}
if(m_reverse_api_device_index_isSet){ isObjectUpdated = true; break;}
}while(false);
return isObjectUpdated;
}
}

View File

@ -0,0 +1,149 @@
/**
* SDRangel
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
*
* OpenAPI spec version: 4.4.0
* Contact: f4exb06@gmail.com
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/*
* SWGXtrxOutputSettings.h
*
* XTRX
*/
#ifndef SWGXtrxOutputSettings_H_
#define SWGXtrxOutputSettings_H_
#include <QJsonObject>
#include <QString>
#include "SWGObject.h"
#include "export.h"
namespace SWGSDRangel {
class SWG_API SWGXtrxOutputSettings: public SWGObject {
public:
SWGXtrxOutputSettings();
SWGXtrxOutputSettings(QString* json);
virtual ~SWGXtrxOutputSettings();
void init();
void cleanup();
virtual QString asJson () override;
virtual QJsonObject* asJsonObject() override;
virtual void fromJsonObject(QJsonObject &json) override;
virtual SWGXtrxOutputSettings* fromJson(QString &jsonString) override;
qint64 getCenterFrequency();
void setCenterFrequency(qint64 center_frequency);
qint32 getDevSampleRate();
void setDevSampleRate(qint32 dev_sample_rate);
qint32 getLog2HardInterp();
void setLog2HardInterp(qint32 log2_hard_interp);
qint32 getLog2SoftInterp();
void setLog2SoftInterp(qint32 log2_soft_interp);
qint32 getLpfBw();
void setLpfBw(qint32 lpf_bw);
qint32 getGain();
void setGain(qint32 gain);
qint32 getNcoEnable();
void setNcoEnable(qint32 nco_enable);
qint32 getNcoFrequency();
void setNcoFrequency(qint32 nco_frequency);
qint32 getAntennaPath();
void setAntennaPath(qint32 antenna_path);
qint32 getExtClock();
void setExtClock(qint32 ext_clock);
qint32 getExtClockFreq();
void setExtClockFreq(qint32 ext_clock_freq);
qint32 getPwrmode();
void setPwrmode(qint32 pwrmode);
qint32 getUseReverseApi();
void setUseReverseApi(qint32 use_reverse_api);
QString* getReverseApiAddress();
void setReverseApiAddress(QString* reverse_api_address);
qint32 getReverseApiPort();
void setReverseApiPort(qint32 reverse_api_port);
qint32 getReverseApiDeviceIndex();
void setReverseApiDeviceIndex(qint32 reverse_api_device_index);
virtual bool isSet() override;
private:
qint64 center_frequency;
bool m_center_frequency_isSet;
qint32 dev_sample_rate;
bool m_dev_sample_rate_isSet;
qint32 log2_hard_interp;
bool m_log2_hard_interp_isSet;
qint32 log2_soft_interp;
bool m_log2_soft_interp_isSet;
qint32 lpf_bw;
bool m_lpf_bw_isSet;
qint32 gain;
bool m_gain_isSet;
qint32 nco_enable;
bool m_nco_enable_isSet;
qint32 nco_frequency;
bool m_nco_frequency_isSet;
qint32 antenna_path;
bool m_antenna_path_isSet;
qint32 ext_clock;
bool m_ext_clock_isSet;
qint32 ext_clock_freq;
bool m_ext_clock_freq_isSet;
qint32 pwrmode;
bool m_pwrmode_isSet;
qint32 use_reverse_api;
bool m_use_reverse_api_isSet;
QString* reverse_api_address;
bool m_reverse_api_address_isSet;
qint32 reverse_api_port;
bool m_reverse_api_port_isSet;
qint32 reverse_api_device_index;
bool m_reverse_api_device_index_isSet;
};
}
#endif /* SWGXtrxOutputSettings_H_ */