mirror of
https://github.com/f4exb/sdrangel.git
synced 2026-06-03 06:24:48 -04:00
Remote input/sink implemented remote control (1)
This commit is contained in:
@@ -21,8 +21,10 @@
|
||||
#include <QDebug>
|
||||
#include <QNetworkReply>
|
||||
#include <QBuffer>
|
||||
#include <QJsonParseError>
|
||||
|
||||
#include "SWGDeviceSettings.h"
|
||||
#include "SWGChannelSettings.h"
|
||||
#include "SWGDeviceState.h"
|
||||
#include "SWGDeviceReport.h"
|
||||
#include "SWGRemoteInputReport.h"
|
||||
@@ -40,6 +42,7 @@ MESSAGE_CLASS_DEFINITION(RemoteInput::MsgConfigureRemoteInputTiming, Message)
|
||||
MESSAGE_CLASS_DEFINITION(RemoteInput::MsgReportRemoteInputAcquisition, Message)
|
||||
MESSAGE_CLASS_DEFINITION(RemoteInput::MsgReportRemoteInputStreamData, Message)
|
||||
MESSAGE_CLASS_DEFINITION(RemoteInput::MsgReportRemoteInputStreamTiming, Message)
|
||||
MESSAGE_CLASS_DEFINITION(RemoteInput::MsgConfigureRemoteChannel, Message)
|
||||
MESSAGE_CLASS_DEFINITION(RemoteInput::MsgStartStop, Message)
|
||||
|
||||
RemoteInput::RemoteInput(DeviceAPI *deviceAPI) :
|
||||
@@ -54,6 +57,7 @@ RemoteInput::RemoteInput(DeviceAPI *deviceAPI) :
|
||||
m_sampleFifo.setSize(m_sampleRate * 8);
|
||||
m_remoteInputUDPHandler = new RemoteInputUDPHandler(&m_sampleFifo, m_deviceAPI);
|
||||
m_remoteInputUDPHandler->setMessageQueueToInput(&m_inputMessageQueue);
|
||||
connect(m_remoteInputUDPHandler, SIGNAL(metaChanged()), this, SLOT(handleMetaChanged()));
|
||||
|
||||
m_deviceAPI->setNbSourceStreams(1);
|
||||
|
||||
@@ -63,6 +67,7 @@ RemoteInput::RemoteInput(DeviceAPI *deviceAPI) :
|
||||
|
||||
RemoteInput::~RemoteInput()
|
||||
{
|
||||
disconnect(m_remoteInputUDPHandler, SIGNAL(metaChanged()), this, SLOT(handleMetaChanged()));
|
||||
disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*)));
|
||||
delete m_networkManager;
|
||||
stop();
|
||||
@@ -200,6 +205,13 @@ bool RemoteInput::handleMessage(const Message& message)
|
||||
MsgConfigureRemoteInput& conf = (MsgConfigureRemoteInput&) message;
|
||||
applySettings(conf.getSettings(), conf.getForce());
|
||||
return true;
|
||||
}
|
||||
else if (MsgConfigureRemoteChannel::match(message))
|
||||
{
|
||||
qDebug() << "RemoteInput::handleMessage:" << message.getIdentifier();
|
||||
MsgConfigureRemoteChannel& conf = (MsgConfigureRemoteChannel&) message;
|
||||
applyRemoteChannelSettings(conf.getSettings());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -248,10 +260,10 @@ void RemoteInput::applySettings(const RemoteInputSettings& settings, bool force)
|
||||
settings.m_iqCorrection ? "true" : "false");
|
||||
}
|
||||
|
||||
if ((m_settings.m_dataAddress != settings.m_dataAddress) ||
|
||||
(m_settings.m_dataPort != settings.m_dataPort) ||
|
||||
(m_settings.m_multicastAddress != settings.m_multicastAddress) ||
|
||||
(m_settings.m_multicastJoin != settings.m_multicastJoin) || force)
|
||||
if ((m_settings.m_dataAddress != settings.m_dataAddress) ||
|
||||
(m_settings.m_dataPort != settings.m_dataPort) ||
|
||||
(m_settings.m_multicastAddress != settings.m_multicastAddress) ||
|
||||
(m_settings.m_multicastJoin != settings.m_multicastJoin) || force)
|
||||
{
|
||||
m_remoteInputUDPHandler->configureUDPLink(settings.m_dataAddress, settings.m_dataPort, settings.m_multicastAddress, settings.m_multicastJoin);
|
||||
m_remoteInputUDPHandler->getRemoteAddress(remoteAddress);
|
||||
@@ -272,13 +284,70 @@ void RemoteInput::applySettings(const RemoteInputSettings& settings, bool force)
|
||||
m_remoteAddress = remoteAddress;
|
||||
|
||||
qDebug() << "RemoteInput::applySettings: "
|
||||
<< " m_dataAddress: " << m_settings.m_dataAddress
|
||||
<< " m_dataPort: " << m_settings.m_dataPort
|
||||
<< " m_multicastAddress: " << m_settings.m_multicastAddress
|
||||
<< " m_multicastJoin: " << m_settings.m_multicastJoin
|
||||
<< " m_apiAddress: " << m_settings.m_apiAddress
|
||||
<< " m_apiPort: " << m_settings.m_apiPort
|
||||
<< " m_remoteAddress: " << m_remoteAddress;
|
||||
<< " m_dataAddress: " << m_settings.m_dataAddress
|
||||
<< " m_dataPort: " << m_settings.m_dataPort
|
||||
<< " m_multicastAddress: " << m_settings.m_multicastAddress
|
||||
<< " m_multicastJoin: " << m_settings.m_multicastJoin
|
||||
<< " m_apiAddress: " << m_settings.m_apiAddress
|
||||
<< " m_apiPort: " << m_settings.m_apiPort
|
||||
<< " m_remoteAddress: " << m_remoteAddress;
|
||||
}
|
||||
|
||||
void RemoteInput::applyRemoteChannelSettings(const RemoteChannelSettings& settings)
|
||||
{
|
||||
SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();;
|
||||
swgChannelSettings->setOriginatorChannelIndex(0);
|
||||
swgChannelSettings->setOriginatorDeviceSetIndex(m_deviceAPI->getDeviceSetIndex());
|
||||
swgChannelSettings->setChannelType(new QString("RemoteSink"));
|
||||
swgChannelSettings->setRemoteSinkSettings(new SWGSDRangel::SWGRemoteSinkSettings());
|
||||
SWGSDRangel::SWGRemoteSinkSettings *swgRemoteSinkSettings = swgChannelSettings->getRemoteSinkSettings();
|
||||
bool hasChanged = false;
|
||||
|
||||
if (settings.m_deviceCenterFrequency != m_remoteChannelSettings.m_deviceCenterFrequency)
|
||||
{
|
||||
swgRemoteSinkSettings->setDeviceCenterFrequency(settings.m_deviceCenterFrequency);
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
if (settings.m_log2Decim != m_remoteChannelSettings.m_log2Decim)
|
||||
{
|
||||
swgRemoteSinkSettings->setLog2Decim(settings.m_log2Decim);
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
if (settings.m_filterChainHash != m_remoteChannelSettings.m_filterChainHash)
|
||||
{
|
||||
swgRemoteSinkSettings->setFilterChainHash(settings.m_filterChainHash);
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
if (hasChanged)
|
||||
{
|
||||
QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
|
||||
.arg(m_settings.m_apiAddress)
|
||||
.arg(m_settings.m_apiPort)
|
||||
.arg(m_currentMeta.m_deviceIndex)
|
||||
.arg(m_currentMeta.m_channelIndex);
|
||||
m_networkRequest.setUrl(QUrl(channelSettingsURL));
|
||||
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
|
||||
QBuffer *buffer = new QBuffer();
|
||||
buffer->open((QBuffer::ReadWrite));
|
||||
buffer->write(swgChannelSettings->asJson().toUtf8());
|
||||
buffer->seek(0);
|
||||
|
||||
// Always use PATCH to avoid passing reverse API settings
|
||||
QNetworkReply *reply = m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer);
|
||||
buffer->setParent(reply);
|
||||
}
|
||||
|
||||
m_remoteChannelSettings = settings;
|
||||
|
||||
qDebug() << "RemoteInput::applyRemoteChannelSettings: "
|
||||
<< " m_deviceCenterFrequency: " << m_remoteChannelSettings.m_deviceCenterFrequency
|
||||
<< " m_deviceSampleRate: " << m_remoteChannelSettings.m_deviceSampleRate
|
||||
<< " m_log2Decim: " << m_remoteChannelSettings.m_log2Decim
|
||||
<< " m_filterChainHash: " << m_remoteChannelSettings.m_filterChainHash;
|
||||
}
|
||||
|
||||
int RemoteInput::webapiRunGet(
|
||||
@@ -534,7 +603,51 @@ void RemoteInput::networkManagerFinished(QNetworkReply *reply)
|
||||
QString answer = reply->readAll();
|
||||
answer.chop(1); // remove last \n
|
||||
qDebug("RemoteInput::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
|
||||
|
||||
QByteArray jsonBytes(answer.toStdString().c_str());
|
||||
QJsonParseError error;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(jsonBytes, &error);
|
||||
|
||||
if (error.error == QJsonParseError::NoError)
|
||||
{
|
||||
if (doc.object().contains("RemoteSinkSettings")) {
|
||||
analyzeRemoteChannelSettingsReply(doc.object());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void RemoteInput::analyzeRemoteChannelSettingsReply(const QJsonObject& jsonObject)
|
||||
{
|
||||
QJsonObject settings = jsonObject["RemoteSinkSettings"].toObject();
|
||||
m_remoteChannelSettings.m_deviceCenterFrequency = settings["deviceCenterFrequency"].toInt();
|
||||
m_remoteChannelSettings.m_deviceSampleRate = settings["deviceSampleRate"].toInt();
|
||||
m_remoteChannelSettings.m_log2Decim = settings["log2Decim"].toInt();
|
||||
m_remoteChannelSettings.m_filterChainHash = settings["filterChainHash"].toInt();
|
||||
|
||||
if (m_guiMessageQueue) // forward to GUI if any
|
||||
{
|
||||
MsgConfigureRemoteChannel *msg = MsgConfigureRemoteChannel::create(m_remoteChannelSettings);
|
||||
m_guiMessageQueue->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteInput::getRemoteChannelSettings()
|
||||
{
|
||||
QString getSettingsURL= QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
|
||||
.arg(m_settings.m_apiAddress)
|
||||
.arg(m_settings.m_apiPort)
|
||||
.arg(m_currentMeta.m_deviceIndex)
|
||||
.arg(m_currentMeta.m_channelIndex);
|
||||
|
||||
m_networkRequest.setUrl(QUrl(getSettingsURL));
|
||||
m_networkManager->get(m_networkRequest);
|
||||
}
|
||||
|
||||
void RemoteInput::handleMetaChanged()
|
||||
{
|
||||
m_currentMeta = m_remoteInputUDPHandler->getCurrentMeta();
|
||||
getRemoteChannelSettings();
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <QNetworkRequest>
|
||||
|
||||
#include "dsp/devicesamplesource.h"
|
||||
#include "channel/remotedatablock.h"
|
||||
|
||||
#include "remoteinputsettings.h"
|
||||
|
||||
@@ -39,6 +40,21 @@ class RemoteInputUDPHandler;
|
||||
class RemoteInput : public DeviceSampleSource {
|
||||
Q_OBJECT
|
||||
public:
|
||||
struct RemoteChannelSettings
|
||||
{
|
||||
uint64_t m_deviceCenterFrequency;
|
||||
uint32_t m_deviceSampleRate;
|
||||
uint32_t m_log2Decim;
|
||||
uint32_t m_filterChainHash;
|
||||
|
||||
RemoteChannelSettings() :
|
||||
m_deviceCenterFrequency(0),
|
||||
m_deviceSampleRate(1),
|
||||
m_log2Decim(0),
|
||||
m_filterChainHash(0)
|
||||
{}
|
||||
};
|
||||
|
||||
class MsgConfigureRemoteInput : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
@@ -125,6 +141,26 @@ public:
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgConfigureRemoteChannel : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
const RemoteChannelSettings& getSettings() const { return m_settings; }
|
||||
|
||||
static MsgConfigureRemoteChannel* create(const RemoteChannelSettings& settings)
|
||||
{
|
||||
return new MsgConfigureRemoteChannel(settings);
|
||||
}
|
||||
|
||||
protected:
|
||||
RemoteChannelSettings m_settings;
|
||||
|
||||
MsgConfigureRemoteChannel(const RemoteChannelSettings& settings) :
|
||||
Message(),
|
||||
m_settings(settings)
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgReportRemoteInputStreamTiming : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
@@ -307,7 +343,9 @@ private:
|
||||
int m_sampleRate;
|
||||
QMutex m_mutex;
|
||||
RemoteInputSettings m_settings;
|
||||
RemoteChannelSettings m_remoteChannelSettings;
|
||||
RemoteInputUDPHandler* m_remoteInputUDPHandler;
|
||||
RemoteMetaDataFEC m_currentMeta;
|
||||
QString m_remoteAddress;
|
||||
QString m_deviceDescription;
|
||||
std::time_t m_startingTimeStamp;
|
||||
@@ -315,12 +353,16 @@ private:
|
||||
QNetworkRequest m_networkRequest;
|
||||
|
||||
void applySettings(const RemoteInputSettings& settings, bool force = false);
|
||||
void applyRemoteChannelSettings(const RemoteChannelSettings& settings);
|
||||
void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response);
|
||||
void webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const RemoteInputSettings& settings, bool force);
|
||||
void webapiReverseSendStartStop(bool start);
|
||||
void getRemoteChannelSettings();
|
||||
void analyzeRemoteChannelSettingsReply(const QJsonObject& jsonObject);
|
||||
|
||||
private slots:
|
||||
void networkManagerFinished(QNetworkReply *reply);
|
||||
void handleMetaChanged();
|
||||
};
|
||||
|
||||
#endif // INCLUDE_REMOTEINPUT_H
|
||||
|
||||
@@ -415,8 +415,6 @@ void RemoteInputBuffer::printMeta(const QString& header, RemoteMetaDataFEC *meta
|
||||
<< ":" << (int) metaData->m_sampleBits
|
||||
<< ":" << (int) metaData->m_nbOriginalBlocks
|
||||
<< ":" << (int) metaData->m_nbFECBlocks
|
||||
<< "|" << metaData->m_deviceCenterFrequency
|
||||
<< ":" << metaData->m_basebandSampleRate
|
||||
<< "|" << metaData->m_deviceIndex
|
||||
<< ":" << metaData->m_channelIndex
|
||||
<< "|" << metaData->m_tv_sec
|
||||
|
||||
@@ -18,11 +18,14 @@
|
||||
#ifndef PLUGINS_SAMPLESOURCE_REMOTEINPUT_REMOTEINPUTBUFFER_H_
|
||||
#define PLUGINS_SAMPLESOURCE_REMOTEINPUT_REMOTEINPUTBUFFER_H_
|
||||
|
||||
#include <channel/remotedatablock.h>
|
||||
#include <QString>
|
||||
#include <QDebug>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "cm256cc/cm256.h"
|
||||
|
||||
#include "channel/remotedatablock.h"
|
||||
#include "util/movingaverage.h"
|
||||
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "gui/basicdevicesettingsdialog.h"
|
||||
#include "dsp/dspengine.h"
|
||||
#include "dsp/dspcommands.h"
|
||||
#include "dsp/hbfilterchainconverter.h"
|
||||
#include "mainwindow.h"
|
||||
#include "util/simpleserializer.h"
|
||||
#include "device/deviceapi.h"
|
||||
@@ -76,6 +77,9 @@ RemoteInputGui::RemoteInputGui(DeviceUISet *deviceUISet, QWidget* parent) :
|
||||
m_startingTimeStampms = 0;
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->remoteDeviceFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
|
||||
ui->remoteDeviceFrequency->setValueRange(8, 0, 99999999);
|
||||
|
||||
CRightClickEnabler *startStopRightClickEnabler = new CRightClickEnabler(ui->startStop);
|
||||
connect(startStopRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(openDeviceSettingsDialog(const QPoint &)));
|
||||
|
||||
@@ -160,6 +164,16 @@ bool RemoteInputGui::handleMessage(const Message& message)
|
||||
blockApplySettings(false);
|
||||
return true;
|
||||
}
|
||||
else if (RemoteInput::MsgConfigureRemoteChannel::match(message))
|
||||
{
|
||||
qDebug("RemoteInputGui::handleMessage: RemoteInput::MsgConfigureRemoteChannel");
|
||||
const RemoteInput::MsgConfigureRemoteChannel& cfg = (RemoteInput::MsgConfigureRemoteChannel&) message;
|
||||
m_remoteChannelSettings = cfg.getSettings();
|
||||
blockApplySettings(true);
|
||||
displayRemoteSettings();
|
||||
blockApplySettings(false);
|
||||
return true;
|
||||
}
|
||||
else if (RemoteInput::MsgReportRemoteInputAcquisition::match(message))
|
||||
{
|
||||
m_acquisition = ((RemoteInput::MsgReportRemoteInputAcquisition&)message).getAcquisition();
|
||||
@@ -286,12 +300,86 @@ void RemoteInputGui::displaySettings()
|
||||
blockApplySettings(false);
|
||||
}
|
||||
|
||||
void RemoteInputGui::displayRemoteSettings()
|
||||
{
|
||||
blockApplySettings(true);
|
||||
ui->remoteDeviceFrequency->setValue(m_remoteChannelSettings.m_deviceCenterFrequency/1000);
|
||||
ui->decimationFactor->setCurrentIndex(m_remoteChannelSettings.m_log2Decim);
|
||||
applyDecimation();
|
||||
blockApplySettings(false);
|
||||
}
|
||||
|
||||
void RemoteInputGui::displayRemoteShift()
|
||||
{
|
||||
int basebandSampleRate = m_streamSampleRate * (1<<m_remoteChannelSettings.m_log2Decim);
|
||||
int shift = m_remoteShiftFrequencyFactor * basebandSampleRate;
|
||||
QLocale loc;
|
||||
ui->offsetFrequencyText->setText(tr("%1 Hz").arg(loc.toString(shift)));
|
||||
}
|
||||
|
||||
void RemoteInputGui::applyDecimation()
|
||||
{
|
||||
uint32_t maxHash = 1;
|
||||
|
||||
for (uint32_t i = 0; i < m_remoteChannelSettings.m_log2Decim; i++) {
|
||||
maxHash *= 3;
|
||||
}
|
||||
|
||||
ui->position->setMaximum(maxHash-1);
|
||||
ui->position->setValue(m_remoteChannelSettings.m_filterChainHash);
|
||||
m_remoteChannelSettings.m_filterChainHash = ui->position->value();
|
||||
applyPosition();
|
||||
}
|
||||
|
||||
void RemoteInputGui::applyPosition()
|
||||
{
|
||||
ui->filterChainIndex->setText(tr("%1").arg(m_remoteChannelSettings.m_filterChainHash));
|
||||
QString s;
|
||||
m_remoteShiftFrequencyFactor = HBFilterChainConverter::convertToString(
|
||||
m_remoteChannelSettings.m_log2Decim,
|
||||
m_remoteChannelSettings.m_filterChainHash, s)
|
||||
;
|
||||
ui->filterChainText->setText(s);
|
||||
|
||||
displayRemoteShift();
|
||||
applyRemoteSettings();
|
||||
}
|
||||
|
||||
void RemoteInputGui::applyRemoteSettings()
|
||||
{
|
||||
if (m_doApplySettings)
|
||||
{
|
||||
qDebug() << "RemoteInputGui::applyRemoteSettings";
|
||||
RemoteInput::MsgConfigureRemoteChannel* message =
|
||||
RemoteInput::MsgConfigureRemoteChannel::create(m_remoteChannelSettings);
|
||||
m_sampleSource->getInputMessageQueue()->push(message);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteInputGui::sendSettings()
|
||||
{
|
||||
if(!m_updateTimer.isActive())
|
||||
m_updateTimer.start(100);
|
||||
}
|
||||
|
||||
void RemoteInputGui::on_remoteDeviceFrequency_changed(quint64 value)
|
||||
{
|
||||
m_remoteChannelSettings.m_deviceCenterFrequency = value * 1000;
|
||||
applyRemoteSettings();
|
||||
}
|
||||
|
||||
void RemoteInputGui::on_decimationFactor_currentIndexChanged(int index)
|
||||
{
|
||||
m_remoteChannelSettings.m_log2Decim = index;
|
||||
applyDecimation();
|
||||
}
|
||||
|
||||
void RemoteInputGui::on_position_valueChanged(int value)
|
||||
{
|
||||
m_remoteChannelSettings.m_filterChainHash = value;
|
||||
applyPosition();
|
||||
}
|
||||
|
||||
void RemoteInputGui::on_apiApplyButton_clicked(bool checked)
|
||||
{
|
||||
(void) checked;
|
||||
|
||||
@@ -55,6 +55,8 @@ private:
|
||||
|
||||
DeviceUISet* m_deviceUISet;
|
||||
RemoteInputSettings m_settings; //!< current settings
|
||||
RemoteInput::RemoteChannelSettings m_remoteChannelSettings;
|
||||
double m_remoteShiftFrequencyFactor; //!< Remote channel frequency shift factor
|
||||
RemoteInput* m_sampleSource;
|
||||
bool m_acquisition;
|
||||
int m_streamSampleRate; //!< Sample rate of received stream
|
||||
@@ -103,6 +105,8 @@ private:
|
||||
|
||||
void blockApplySettings(bool block);
|
||||
void displaySettings();
|
||||
void displayRemoteSettings();
|
||||
void displayRemoteShift();
|
||||
void displayTime();
|
||||
void sendSettings();
|
||||
void updateWithAcquisition();
|
||||
@@ -110,11 +114,17 @@ private:
|
||||
void updateSampleRateAndFrequency();
|
||||
void displayEventCounts();
|
||||
void displayEventTimer();
|
||||
void applyDecimation();
|
||||
void applyPosition();
|
||||
void applyRemoteSettings();
|
||||
void analyzeApiReply(const QJsonObject& jsonObject);
|
||||
bool handleMessage(const Message& message);
|
||||
|
||||
private slots:
|
||||
void handleInputMessages();
|
||||
void on_remoteDeviceFrequency_changed(quint64 value);
|
||||
void on_decimationFactor_currentIndexChanged(int index);
|
||||
void on_position_valueChanged(int value);
|
||||
void on_apiApplyButton_clicked(bool checked);
|
||||
void on_dataApplyButton_clicked(bool checked);
|
||||
void on_dcOffset_toggled(bool checked);
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>312</height>
|
||||
<height>480</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>360</width>
|
||||
<height>270</height>
|
||||
<height>480</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
@@ -27,7 +27,7 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
@@ -162,6 +162,252 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="remoteDevFreqLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="remoteFrequencyLabel">
|
||||
<property name="text">
|
||||
<string>Rem dev Fc</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ValueDial" name="remoteDeviceFrequency" 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>Remote device center ferquency in kHz</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="remoteDeviceFreqUnits">
|
||||
<property name="text">
|
||||
<string>kHz</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_9">
|
||||
<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>
|
||||
<layout class="QVBoxLayout" name="remoteChDecimationLayer">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="decimationStageLayer">
|
||||
<item>
|
||||
<widget class="QLabel" name="decimationLabel">
|
||||
<property name="text">
|
||||
<string>Dec</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="decimationFactor">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>55</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Decimation factor</string>
|
||||
</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>
|
||||
<widget class="QLabel" name="channelRateText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Effective channel rate (kS/s)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0000k</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="filterChainText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Filter chain stages left to right (L: low, C: center, H: high) </string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>LLLLLL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<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="offsetFrequencyText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>85</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Offset frequency with thousands separator (Hz)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-9,999,999 Hz</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="decimationShiftLayer">
|
||||
<property name="rightMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="positionLabel">
|
||||
<property name="text">
|
||||
<string>Pos</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="position">
|
||||
<property name="toolTip">
|
||||
<string>Center frequency position</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="filterChainIndex">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Filter chain hash code</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>000</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="gridLayout_corr">
|
||||
<item>
|
||||
@@ -860,6 +1106,12 @@
|
||||
<extends>QToolButton</extends>
|
||||
<header>gui/buttonswitch.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ValueDial</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/valuedial.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../../sdrgui/resources/res.qrc"/>
|
||||
|
||||
@@ -324,6 +324,13 @@ void RemoteInputUDPHandler::tick()
|
||||
}
|
||||
|
||||
const RemoteMetaDataFEC& metaData = m_remoteInputBuffer.getCurrentMeta();
|
||||
|
||||
if (!(m_currentMeta == metaData))
|
||||
{
|
||||
m_currentMeta = metaData;
|
||||
emit metaChanged();
|
||||
}
|
||||
|
||||
m_readLength = m_readLengthSamples * (metaData.m_sampleBytes & 0xF) * 2;
|
||||
|
||||
if (metaData.m_sampleBits == SDR_RX_SAMP_SZ) // no conversion
|
||||
@@ -409,56 +416,6 @@ void RemoteInputUDPHandler::tick()
|
||||
qWarning("RemoteInputUDPHandler::tick: unexpected sample size in stream: %d bits", (int) metaData.m_sampleBits);
|
||||
}
|
||||
|
||||
// if ((metaData.m_sampleBits == 16) && (SDR_RX_SAMP_SZ == 24)) // 16 -> 24 bits
|
||||
// {
|
||||
// if (m_readLengthSamples > (int) m_converterBufferNbSamples)
|
||||
// {
|
||||
// if (m_converterBuffer) { delete[] m_converterBuffer; }
|
||||
// m_converterBuffer = new int32_t[m_readLengthSamples*2];
|
||||
// }
|
||||
|
||||
// uint8_t *buf = m_remoteInputBuffer.readData(m_readLength);
|
||||
|
||||
// for (int is = 0; is < m_readLengthSamples; is++)
|
||||
// {
|
||||
// m_converterBuffer[2*is] = ((int16_t*)buf)[2*is]; // I
|
||||
// m_converterBuffer[2*is]<<=8;
|
||||
// m_converterBuffer[2*is+1] = ((int16_t*)buf)[2*is+1]; // Q
|
||||
// m_converterBuffer[2*is+1]<<=8;
|
||||
// }
|
||||
|
||||
// m_sampleFifo->write(reinterpret_cast<quint8*>(m_converterBuffer), m_readLengthSamples*sizeof(Sample));
|
||||
// }
|
||||
// else if ((metaData.m_sampleBits == 24) && (SDR_RX_SAMP_SZ == 16)) // 24 -> 16 bits
|
||||
// {
|
||||
// if (m_readLengthSamples > (int) m_converterBufferNbSamples)
|
||||
// {
|
||||
// if (m_converterBuffer) { delete[] m_converterBuffer; }
|
||||
// m_converterBuffer = new int32_t[m_readLengthSamples];
|
||||
// }
|
||||
|
||||
// uint8_t *buf = m_remoteInputBuffer.readData(m_readLength);
|
||||
|
||||
// for (int is = 0; is < m_readLengthSamples; is++)
|
||||
// {
|
||||
// m_converterBuffer[is] = ((int32_t *)buf)[2*is+1]>>8; // Q -> MSB
|
||||
// m_converterBuffer[is] <<=16;
|
||||
// m_converterBuffer[is] += ((int32_t *)buf)[2*is]>>8; // I -> LSB
|
||||
// }
|
||||
|
||||
// m_sampleFifo->write(reinterpret_cast<quint8*>(m_converterBuffer), m_readLengthSamples*sizeof(Sample));
|
||||
// }
|
||||
// else if ((metaData.m_sampleBits == 16) || (metaData.m_sampleBits == 24)) // same sample size and valid size
|
||||
// {
|
||||
// // read samples directly feeding the SampleFifo (no callback)
|
||||
// m_sampleFifo->write(reinterpret_cast<quint8*>(m_remoteInputBuffer.readData(m_readLength)), m_readLength);
|
||||
// m_samplesCount += m_readLengthSamples;
|
||||
// }
|
||||
// else // invalid size
|
||||
// {
|
||||
// qWarning("RemoteInputUDPHandler::tick: unexpected sample size in stream: %d bits", (int) metaData.m_sampleBits);
|
||||
// }
|
||||
|
||||
if (m_tickCount < m_rateDivider)
|
||||
{
|
||||
m_tickCount++;
|
||||
|
||||
@@ -74,9 +74,14 @@ public:
|
||||
uint64_t getTVmSec() const { return m_tv_msec; }
|
||||
int getMinNbBlocks() { return m_remoteInputBuffer.getMinNbBlocks(); }
|
||||
int getMaxNbRecovery() { return m_remoteInputBuffer.getMaxNbRecovery(); }
|
||||
const RemoteMetaDataFEC& getCurrentMeta() const { return m_currentMeta; }
|
||||
|
||||
public slots:
|
||||
void dataReadyRead();
|
||||
|
||||
signals:
|
||||
void metaChanged();
|
||||
|
||||
private:
|
||||
class MsgUDPAddressAndPort : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
@@ -113,6 +118,7 @@ private:
|
||||
bool m_running;
|
||||
uint32_t m_rateDivider;
|
||||
RemoteInputBuffer m_remoteInputBuffer;
|
||||
RemoteMetaDataFEC m_currentMeta;
|
||||
QUdpSocket *m_dataSocket;
|
||||
QHostAddress m_dataAddress;
|
||||
QHostAddress m_remoteAddress;
|
||||
|
||||
Reference in New Issue
Block a user