Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instant Replay #1900

Merged
merged 4 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion plugins/channelrx/demodadsb/adsbdemodgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,6 @@ QString Aircraft::getLabel(const ADSBDemodSettings *settings) const
if (m_altitudeValid)
{
QStringList row1;
int transitionAlt = 6500;
QChar c = m_altitude >= settings->m_transitionAlt ? 'F' : 'A';
// Convert altitude to flight level
int fl = m_altitude / 100;
Expand Down
1 change: 0 additions & 1 deletion plugins/channelrx/demodam/amdemodgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,6 @@ void AMDemodGUI::on_deltaFrequency_changed(qint64 value)
(void) value;

qint64 offset = 0;
bool valid = true;

if (m_settings.m_frequencyMode == AMDemodSettings::Offset)
{
Expand Down
2 changes: 2 additions & 0 deletions plugins/channelrx/freqscanner/freqscanneraddrangedialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ FreqScannerAddRangeDialog::FreqScannerAddRangeDialog(int step, QWidget* parent)
QDialog(parent),
ui(new Ui::FreqScannerAddRangeDialog)
{
(void) step;

ui->setupUi(this);

ui->start->setColorMapper(ColorMapper(ColorMapper::GrayGold));
Expand Down
2 changes: 1 addition & 1 deletion plugins/feature/startracker/startrackergui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1942,7 +1942,7 @@ void StarTrackerGUI::plotElevationPolarChart()
// Plot rotator position
QString ourSourceName = QString("F0:%1 %2").arg(m_starTracker->getIndexInFeatureSet()).arg(m_starTracker->getIdentifier()); // Only one feature set in practice?
std::vector<FeatureSet*>& featureSets = MainCore::instance()->getFeatureeSets();
for (int featureSetIndex = 0; featureSetIndex < featureSets.size(); featureSetIndex++)
for (int featureSetIndex = 0; featureSetIndex < (int)featureSets.size(); featureSetIndex++)
{
FeatureSet *featureSet = featureSets[featureSetIndex];
for (int featureIndex = 0; featureIndex < featureSet->getNumberOfFeatures(); featureIndex++)
Expand Down
105 changes: 105 additions & 0 deletions plugins/samplesource/airspyhf/airspyhfgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ void AirspyHFGui::displaySettings()
ui->dcOffset->setChecked(m_settings.m_dcBlock);
ui->iqImbalance->setChecked(m_settings.m_iqCorrection);
displayAGC();
displayReplayLength();
displayReplayOffset();
displayReplayStep();
ui->replayLoop->setChecked(m_settings.m_replayLoop);
blockApplySettings(false);
}

Expand Down Expand Up @@ -500,6 +504,9 @@ void AirspyHFGui::openDeviceSettingsDialog(const QPoint& p)
if (m_contextMenuType == ContextMenuDeviceSettings)
{
BasicDeviceSettingsDialog dialog(this);
dialog.setReplayBytesPerSecond(getDevSampleRate(m_settings.m_devSampleRateIndex) * 2 * sizeof(float));
dialog.setReplayLength(m_settings.m_replayLength);
dialog.setReplayStep(m_settings.m_replayStep);
dialog.setUseReverseAPI(m_settings.m_useReverseAPI);
dialog.setReverseAPIAddress(m_settings.m_reverseAPIAddress);
dialog.setReverseAPIPort(m_settings.m_reverseAPIPort);
Expand All @@ -513,17 +520,109 @@ void AirspyHFGui::openDeviceSettingsDialog(const QPoint& p)
m_settings.m_reverseAPIAddress = dialog.getReverseAPIAddress();
m_settings.m_reverseAPIPort = dialog.getReverseAPIPort();
m_settings.m_reverseAPIDeviceIndex = dialog.getReverseAPIDeviceIndex();
m_settings.m_replayLength = dialog.getReplayLength();
m_settings.m_replayStep = dialog.getReplayStep();
displayReplayLength();
displayReplayOffset();
displayReplayStep();
m_settingsKeys.append("useReverseAPI");
m_settingsKeys.append("reverseAPIAddress");
m_settingsKeys.append("reverseAPIPort");
m_settingsKeys.append("reverseAPIDeviceIndex");
m_settingsKeys.append("replayLength");
m_settingsKeys.append("replayStep");

sendSettings();
}

resetContextMenuType();
}

void AirspyHFGui::displayReplayLength()
{
bool replayEnabled = m_settings.m_replayLength > 0.0f;
if (!replayEnabled) {
ui->replayOffset->setMaximum(0);
} else {
ui->replayOffset->setMaximum(m_settings.m_replayLength * 10 - 1);
}
ui->replayLabel->setEnabled(replayEnabled);
ui->replayOffset->setEnabled(replayEnabled);
ui->replayOffsetText->setEnabled(replayEnabled);
ui->replaySave->setEnabled(replayEnabled);
}

void AirspyHFGui::displayReplayOffset()
{
bool replayEnabled = m_settings.m_replayLength > 0.0f;
ui->replayOffset->setValue(m_settings.m_replayOffset * 10);
ui->replayOffsetText->setText(QString("%1s").arg(m_settings.m_replayOffset, 0, 'f', 1));
ui->replayNow->setEnabled(replayEnabled && (m_settings.m_replayOffset > 0.0f));
ui->replayPlus->setEnabled(replayEnabled && (std::round(m_settings.m_replayOffset * 10) < ui->replayOffset->maximum()));
ui->replayMinus->setEnabled(replayEnabled && (m_settings.m_replayOffset > 0.0f));
}

void AirspyHFGui::displayReplayStep()
{
QString step;
float intpart;
float frac = modf(m_settings.m_replayStep, &intpart);
if (frac == 0.0f) {
step = QString::number((int)intpart);
} else {
step = QString::number(m_settings.m_replayStep, 'f', 1);
}
ui->replayPlus->setText(QString("+%1s").arg(step));
ui->replayPlus->setToolTip(QString("Add %1 seconds to time delay").arg(step));
ui->replayMinus->setText(QString("-%1s").arg(step));
ui->replayMinus->setToolTip(QString("Remove %1 seconds from time delay").arg(step));
}

void AirspyHFGui::on_replayOffset_valueChanged(int value)
{
m_settings.m_replayOffset = value / 10.0f;
displayReplayOffset();
m_settingsKeys.append("replayOffset");
sendSettings();
}

void AirspyHFGui::on_replayNow_clicked()
{
ui->replayOffset->setValue(0);
}

void AirspyHFGui::on_replayPlus_clicked()
{
ui->replayOffset->setValue(ui->replayOffset->value() + m_settings.m_replayStep * 10);
}

void AirspyHFGui::on_replayMinus_clicked()
{
ui->replayOffset->setValue(ui->replayOffset->value() - m_settings.m_replayStep * 10);
}

void AirspyHFGui::on_replaySave_clicked()
{
QFileDialog fileDialog(nullptr, "Select file to save IQ data to", "", "*.wav");
fileDialog.setAcceptMode(QFileDialog::AcceptSave);
if (fileDialog.exec())
{
QStringList fileNames = fileDialog.selectedFiles();
if (fileNames.size() > 0)
{
AirspyHFInput::MsgSaveReplay *message = AirspyHFInput::MsgSaveReplay::create(fileNames[0]);
m_sampleSource->getInputMessageQueue()->push(message);
}
}
}

void AirspyHFGui::on_replayLoop_toggled(bool checked)
{
m_settings.m_replayLoop = checked;
m_settingsKeys.append("replayLoop");
sendSettings();
}

void AirspyHFGui::makeUIConnections()
{
QObject::connect(ui->centerFrequency, &ValueDial::changed, this, &AirspyHFGui::on_centerFrequency_changed);
Expand All @@ -540,4 +639,10 @@ void AirspyHFGui::makeUIConnections()
QObject::connect(ui->lna, &ButtonSwitch::toggled, this, &AirspyHFGui::on_lna_toggled);
QObject::connect(ui->agc, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AirspyHFGui::on_agc_currentIndexChanged);
QObject::connect(ui->att, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AirspyHFGui::on_att_currentIndexChanged);
QObject::connect(ui->replayOffset, &QSlider::valueChanged, this, &AirspyHFGui::on_replayOffset_valueChanged);
QObject::connect(ui->replayNow, &QToolButton::clicked, this, &AirspyHFGui::on_replayNow_clicked);
QObject::connect(ui->replayPlus, &QToolButton::clicked, this, &AirspyHFGui::on_replayPlus_clicked);
QObject::connect(ui->replayMinus, &QToolButton::clicked, this, &AirspyHFGui::on_replayMinus_clicked);
QObject::connect(ui->replaySave, &QToolButton::clicked, this, &AirspyHFGui::on_replaySave_clicked);
QObject::connect(ui->replayLoop, &ButtonSwitch::toggled, this, &AirspyHFGui::on_replayLoop_toggled);
}
9 changes: 9 additions & 0 deletions plugins/samplesource/airspyhf/airspyhfgui.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ class AirspyHFGui : public DeviceGUI {
void displaySettings();
void displaySampleRates();
void displayAGC();
void displayReplayLength();
void displayReplayOffset();
void displayReplayStep();
void sendSettings();
void updateSampleRateAndFrequency();
void updateFrequencyLimits();
Expand All @@ -94,6 +97,12 @@ private slots:
void updateHardware();
void updateStatus();
void handleInputMessages();
void on_replayOffset_valueChanged(int value);
void on_replayNow_clicked();
void on_replayPlus_clicked();
void on_replayMinus_clicked();
void on_replaySave_clicked();
void on_replayLoop_toggled(bool checked);
void openDeviceSettingsDialog(const QPoint& p);
};

Expand Down
111 changes: 108 additions & 3 deletions plugins/samplesource/airspyhf/airspyhfgui.ui
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>360</width>
<height>137</height>
<height>175</height>
</rect>
</property>
<property name="sizePolicy">
Expand All @@ -19,13 +19,13 @@
<property name="minimumSize">
<size>
<width>360</width>
<height>137</height>
<height>175</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>380</width>
<height>177</height>
<height>175</height>
</size>
</property>
<property name="font">
Expand Down Expand Up @@ -584,6 +584,111 @@
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="replayLayout">
<item>
<widget class="QLabel" name="replayLabel">
<property name="minimumSize">
<size>
<width>65</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Time Delay</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="replayOffset">
<property name="toolTip">
<string>Replay time delay in seconds</string>
</property>
<property name="maximum">
<number>500</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="replayOffsetText">
<property name="toolTip">
<string>Replay time delay in seconds</string>
</property>
<property name="text">
<string>0.0s</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="replayNow">
<property name="toolTip">
<string>Set time delay to 0 seconds</string>
</property>
<property name="text">
<string>Now</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="replayPlus">
<property name="toolTip">
<string>Add displayed number of seconds to time delay</string>
</property>
<property name="text">
<string>+5s</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="replayMinus">
<property name="toolTip">
<string>Remove displayed number of seconds from time delay</string>
</property>
<property name="text">
<string>-5s</string>
</property>
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="replayLoop">
<property name="toolTip">
<string>Repeatedly replay data in replay buffer</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/playloop.png</normaloff>:/playloop.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="replaySave">
<property name="toolTip">
<string>Save replay buffer to a file</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/save.png</normaloff>:/save.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
Expand Down
Loading