mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-25 17:28:50 -05:00
Merge pull request #1876 from srcejon/freq_scanner
AM Demod: Add additional modes to specify channel center frequency
This commit is contained in:
commit
18458dc567
12
.github/workflows/sdrangel.yml
vendored
12
.github/workflows/sdrangel.yml
vendored
@ -100,7 +100,7 @@ jobs:
|
||||
files: ${{ github.workspace }}/build/sdrangel-${{ steps.get_version.outputs.version }}-win64.exe
|
||||
|
||||
build_mac:
|
||||
runs-on: macos-12
|
||||
runs-on: macos-13
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
@ -109,7 +109,15 @@ jobs:
|
||||
- name: Update brew
|
||||
run: brew update
|
||||
- name: Install brew packages
|
||||
run: brew install nasm boost hidapi libusb fftw ffmpeg faad2 zlib airspy airspyhf hackrf rtl-sdr libbladerf soapysdr qt uhd
|
||||
run: brew install nasm boost hidapi libusb fftw ffmpeg faad2 zlib airspy airspyhf hackrf rtl-sdr libbladerf soapysdr qt
|
||||
- name: Install brew uhd package
|
||||
run: |
|
||||
rm -f /usr/local/bin/2to3*
|
||||
rm -f /usr/local/bin/idle3
|
||||
rm -f /usr/local/bin/pydoc3
|
||||
rm -f /usr/local/bin/python3
|
||||
rm -f /usr/local/bin/python3-config
|
||||
brew install uhd
|
||||
- name: Install brew opencv package
|
||||
run: |
|
||||
rm -f /usr/local/bin/2to3
|
||||
|
@ -226,6 +226,9 @@ void AMDemod::applySettings(const AMDemodSettings& settings, bool force)
|
||||
<< " m_audioDeviceName: " << settings.m_audioDeviceName
|
||||
<< " m_pll: " << settings.m_pll
|
||||
<< " m_syncAMOperation: " << (int) settings.m_syncAMOperation
|
||||
<< " m_frequencyMode: " << settings.m_frequencyMode
|
||||
<< " m_frequency: " << settings.m_frequency
|
||||
<< " m_snap: " << settings.m_snap
|
||||
<< " m_streamIndex: " << settings.m_streamIndex
|
||||
<< " m_useReverseAPI: " << settings.m_useReverseAPI
|
||||
<< " m_reverseAPIAddress: " << settings.m_reverseAPIAddress
|
||||
@ -276,6 +279,16 @@ void AMDemod::applySettings(const AMDemodSettings& settings, bool force)
|
||||
reverseAPIKeys.append("volume");
|
||||
}
|
||||
|
||||
if ((m_settings.m_frequencyMode != settings.m_frequencyMode) || force) {
|
||||
reverseAPIKeys.append("frequencyMode");
|
||||
}
|
||||
if ((m_settings.m_frequency != settings.m_frequency) || force) {
|
||||
reverseAPIKeys.append("frequency");
|
||||
}
|
||||
if ((m_settings.m_snap != settings.m_snap) || force) {
|
||||
reverseAPIKeys.append("snap");
|
||||
}
|
||||
|
||||
if (m_settings.m_streamIndex != settings.m_streamIndex)
|
||||
{
|
||||
if (m_deviceAPI->getSampleMIMO()) // change of stream is possible for MIMO devices only
|
||||
@ -448,6 +461,18 @@ void AMDemod::webapiUpdateChannelSettings(
|
||||
AMDemodSettings::SyncAMLSB : (AMDemodSettings::SyncAMOperation) syncAMOperationCode;
|
||||
}
|
||||
|
||||
if (channelSettingsKeys.contains("frequencyMode")) {
|
||||
settings.m_frequencyMode = (AMDemodSettings::FrequencyMode) response.getAmDemodSettings()->getFrequencyMode();
|
||||
}
|
||||
|
||||
if (channelSettingsKeys.contains("frequency")) {
|
||||
settings.m_frequency = response.getAmDemodSettings()->getFrequency();
|
||||
}
|
||||
|
||||
if (channelSettingsKeys.contains("snap")) {
|
||||
settings.m_snap = (bool) response.getAmDemodSettings()->getSnap();
|
||||
}
|
||||
|
||||
if (channelSettingsKeys.contains("streamIndex")) {
|
||||
settings.m_streamIndex = response.getAmDemodSettings()->getStreamIndex();
|
||||
}
|
||||
@ -510,6 +535,9 @@ void AMDemod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& respo
|
||||
|
||||
response.getAmDemodSettings()->setPll(settings.m_pll ? 1 : 0);
|
||||
response.getAmDemodSettings()->setSyncAmOperation((int) settings.m_syncAMOperation);
|
||||
response.getAmDemodSettings()->setFrequencyMode((int) settings.m_frequencyMode);
|
||||
response.getAmDemodSettings()->setFrequency(settings.m_frequency);
|
||||
response.getAmDemodSettings()->setSnap((int) settings.m_snap);
|
||||
response.getAmDemodSettings()->setStreamIndex(settings.m_streamIndex);
|
||||
response.getAmDemodSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
|
||||
|
||||
@ -669,6 +697,15 @@ void AMDemod::webapiFormatChannelSettings(
|
||||
if (channelSettingsKeys.contains("syncAMOperation") || force) {
|
||||
swgAMDemodSettings->setSyncAmOperation((int) settings.m_syncAMOperation);
|
||||
}
|
||||
if (channelSettingsKeys.contains("frequencyMode") || force) {
|
||||
swgAMDemodSettings->setFrequencyMode((int) settings.m_frequencyMode);
|
||||
}
|
||||
if (channelSettingsKeys.contains("frequency") || force) {
|
||||
swgAMDemodSettings->setFrequency(settings.m_frequency);
|
||||
}
|
||||
if (channelSettingsKeys.contains("snap") || force) {
|
||||
swgAMDemodSettings->setSnap(settings.m_snap);
|
||||
}
|
||||
if (channelSettingsKeys.contains("streamIndex") || force) {
|
||||
swgAMDemodSettings->setStreamIndex(settings.m_streamIndex);
|
||||
}
|
||||
|
@ -91,8 +91,7 @@ bool AMDemodGUI::handleMessage(const Message& message)
|
||||
DSPSignalNotification& notif = (DSPSignalNotification&) message;
|
||||
m_deviceCenterFrequency = notif.getCenterFrequency();
|
||||
m_basebandSampleRate = notif.getSampleRate();
|
||||
ui->deltaFrequency->setValueRange(false, 7, -m_basebandSampleRate/2, m_basebandSampleRate/2);
|
||||
ui->deltaFrequencyLabel->setToolTip(tr("Range %1 %L2 Hz").arg(QChar(0xB1)).arg(m_basebandSampleRate/2));
|
||||
calcOffset();
|
||||
updateAbsoluteCenterFrequency();
|
||||
|
||||
return true;
|
||||
@ -114,11 +113,78 @@ void AMDemodGUI::handleInputMessages()
|
||||
}
|
||||
}
|
||||
|
||||
void AMDemodGUI::channelMarkerChangedByCursor()
|
||||
// Convert from 8.33k channel to frequency in Hz
|
||||
static int channelToFreq(int channel, bool& invalid)
|
||||
{
|
||||
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
|
||||
m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
|
||||
applySettings();
|
||||
qint64 upper = channel / 100;
|
||||
qint64 lower = channel % 100;
|
||||
qint64 low = 0;
|
||||
if (lower <= 7) {
|
||||
low = 0;
|
||||
} else if (lower <= 12) {
|
||||
low = 8333;
|
||||
} else if (lower <= 19) {
|
||||
low = 16666;
|
||||
} else if (lower <= 32) {
|
||||
low = 25000;
|
||||
} else if (lower <= 39) {
|
||||
low = 33333;
|
||||
} else if (lower <= 49) {
|
||||
low = 41666;
|
||||
} else if (lower <= 59) {
|
||||
low = 50000;
|
||||
} else if (lower <= 62) {
|
||||
low = 58333;
|
||||
} else if (lower <= 79) {
|
||||
low = 66666;
|
||||
} else if (lower <= 82) {
|
||||
low = 75000;
|
||||
} else if (lower <= 89) {
|
||||
low = 83333;
|
||||
} else {
|
||||
low = 91666;
|
||||
}
|
||||
const QList<int> validOffsets = {5, 10, 15, 30, 35, 40, 55, 60, 65, 80, 85, 90};
|
||||
invalid = !validOffsets.contains(lower);
|
||||
return upper * 100000 + low;
|
||||
}
|
||||
|
||||
// Convert from frequency in Hz to 8.33k channel in Hz
|
||||
static int freqToChannel(qint64 frequency)
|
||||
{
|
||||
int upper = frequency / 100000;
|
||||
int lower = frequency % 100000;
|
||||
int low = 0;
|
||||
|
||||
if (lower <= 4166) {
|
||||
low = 5;
|
||||
} else if (lower <= 12500) {
|
||||
low = 10;
|
||||
} else if (lower <= 20833) {
|
||||
low = 15;
|
||||
} else if (lower <= 29166) {
|
||||
low = 30;
|
||||
} else if (lower <= 37500) {
|
||||
low = 35;
|
||||
} else if (lower <= 45833) {
|
||||
low = 40;
|
||||
} else if (lower <= 54166) {
|
||||
low = 55;
|
||||
} else if (lower <= 62500) {
|
||||
low = 60;
|
||||
} else if (lower <= 70833) {
|
||||
low = 65;
|
||||
} else if (lower <= 79166) {
|
||||
low = 80;
|
||||
} else if (lower <= 87500) {
|
||||
low = 85;
|
||||
} else if (lower <= 95833) {
|
||||
low = 90;
|
||||
} else {
|
||||
low = 105;
|
||||
}
|
||||
int channel = upper * 100000 + low * 1000;
|
||||
return channel;
|
||||
}
|
||||
|
||||
void AMDemodGUI::channelMarkerHighlightedByCursor()
|
||||
@ -126,9 +192,120 @@ void AMDemodGUI::channelMarkerHighlightedByCursor()
|
||||
setHighlighted(m_channelMarker.getHighlighted());
|
||||
}
|
||||
|
||||
void AMDemodGUI::on_frequencyMode_currentIndexChanged(int index)
|
||||
{
|
||||
m_settings.m_frequencyMode = (AMDemodSettings::FrequencyMode) index;
|
||||
ui->deltaFrequency->blockSignals(true);
|
||||
if (m_settings.m_frequencyMode == AMDemodSettings::Offset)
|
||||
{
|
||||
ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
|
||||
ui->deltaFrequency->setValue(m_settings.m_inputFrequencyOffset);
|
||||
ui->deltaUnits->setText("Hz");
|
||||
if (m_settings.m_snap)
|
||||
{
|
||||
m_settings.m_snap = false;
|
||||
displaySnap();
|
||||
}
|
||||
}
|
||||
else if (m_settings.m_frequencyMode == AMDemodSettings::MediumWave)
|
||||
{
|
||||
ui->deltaFrequency->setValueRange(true, 4, 0, 9999, 0);
|
||||
ui->deltaFrequency->setValue(m_settings.m_frequency / 1000);
|
||||
ui->deltaUnits->setText("kHz");
|
||||
}
|
||||
else if (m_settings.m_frequencyMode == AMDemodSettings::Airband25k)
|
||||
{
|
||||
ui->deltaFrequency->setValueRange(true, 6, 0, 999999, 3);
|
||||
ui->deltaFrequency->setValue(m_settings.m_frequency / 1000);
|
||||
ui->deltaUnits->setText("MHz");
|
||||
}
|
||||
else if (m_settings.m_frequencyMode == AMDemodSettings::Airband8K)
|
||||
{
|
||||
ui->deltaFrequency->setValueRange(true, 6, 118005, 136990, 3);
|
||||
ui->deltaFrequency->setValue(freqToChannel(m_settings.m_frequency) / 1000);
|
||||
ui->deltaUnits->setText("MHz");
|
||||
}
|
||||
ui->deltaFrequency->blockSignals(false);
|
||||
if (m_settings.m_snap) {
|
||||
applySnap();
|
||||
}
|
||||
applySettings();
|
||||
}
|
||||
|
||||
// Calculate input frequency offset, when device center frequency changes
|
||||
void AMDemodGUI::calcOffset()
|
||||
{
|
||||
if (m_settings.m_frequencyMode == AMDemodSettings::Offset)
|
||||
{
|
||||
ui->deltaFrequency->setValueRange(false, 7, -m_basebandSampleRate/2, m_basebandSampleRate/2);
|
||||
}
|
||||
else
|
||||
{
|
||||
qint64 offset = m_settings.m_frequency - m_deviceCenterFrequency;
|
||||
m_channelMarker.setCenterFrequency(offset);
|
||||
m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
|
||||
updateAbsoluteCenterFrequency();
|
||||
applySettings();
|
||||
}
|
||||
}
|
||||
|
||||
void AMDemodGUI::channelMarkerChangedByCursor()
|
||||
{
|
||||
m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
|
||||
if (m_settings.m_snap) {
|
||||
applySnap();
|
||||
}
|
||||
m_settings.m_frequency = m_deviceCenterFrequency + m_settings.m_inputFrequencyOffset;
|
||||
int value = 0;
|
||||
if (m_settings.m_frequencyMode == AMDemodSettings::Offset) {
|
||||
value = m_settings.m_inputFrequencyOffset;
|
||||
} else if (m_settings.m_frequencyMode == AMDemodSettings::MediumWave) {
|
||||
value = m_settings.m_frequency / 1000;
|
||||
} else if (m_settings.m_frequencyMode == AMDemodSettings::Airband25k) {
|
||||
value = m_settings.m_frequency / 1000;
|
||||
} else if (m_settings.m_frequencyMode == AMDemodSettings::Airband8K) {
|
||||
value = freqToChannel(m_settings.m_frequency) / 1000;
|
||||
}
|
||||
|
||||
// We support finer tuning by marker than by deltaFrequency widget (unless in offset mode),
|
||||
// so block signals so it doesn't truncate frequency to limit of widget
|
||||
ui->deltaFrequency->blockSignals(true);
|
||||
ui->deltaFrequency->setValue(value);
|
||||
ui->deltaFrequency->blockSignals(false);
|
||||
|
||||
updateAbsoluteCenterFrequency();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void AMDemodGUI::on_deltaFrequency_changed(qint64 value)
|
||||
{
|
||||
m_channelMarker.setCenterFrequency(value);
|
||||
(void) value;
|
||||
|
||||
qint64 offset = 0;
|
||||
bool valid = true;
|
||||
|
||||
if (m_settings.m_frequencyMode == AMDemodSettings::Offset)
|
||||
{
|
||||
offset = value;
|
||||
m_settings.m_frequency = m_deviceCenterFrequency + offset;
|
||||
}
|
||||
else if (m_settings.m_frequencyMode == AMDemodSettings::MediumWave)
|
||||
{
|
||||
m_settings.m_frequency = value * 1000;
|
||||
offset = m_settings.m_frequency - m_deviceCenterFrequency;
|
||||
}
|
||||
else if (m_settings.m_frequencyMode == AMDemodSettings::Airband25k)
|
||||
{
|
||||
m_settings.m_frequency = value * 1000;
|
||||
offset = m_settings.m_frequency - m_deviceCenterFrequency;
|
||||
}
|
||||
else if (m_settings.m_frequencyMode == AMDemodSettings::Airband8K)
|
||||
{
|
||||
m_settings.m_frequency = channelToFreq(value, m_invalidChannel);
|
||||
offset = m_settings.m_frequency - m_deviceCenterFrequency;
|
||||
}
|
||||
|
||||
m_channelMarker.setCenterFrequency(offset);
|
||||
m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
|
||||
updateAbsoluteCenterFrequency();
|
||||
applySettings();
|
||||
@ -267,7 +444,8 @@ AMDemodGUI::AMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandS
|
||||
m_squelchOpen(false),
|
||||
m_audioSampleRate(-1),
|
||||
m_samUSB(true),
|
||||
m_tickCount(0)
|
||||
m_tickCount(0),
|
||||
m_invalidChannel(false)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
m_helpURL = "plugins/channelrx/demodam/readme.md";
|
||||
@ -289,7 +467,9 @@ AMDemodGUI::AMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandS
|
||||
CRightClickEnabler *samSidebandRightClickEnabler = new CRightClickEnabler(ui->ssb);
|
||||
connect(samSidebandRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(samSSBSelect(const QPoint &)));
|
||||
|
||||
ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
|
||||
CRightClickEnabler *frequencyModeRightClickEnabler = new CRightClickEnabler(ui->frequencyMode);
|
||||
connect(frequencyModeRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(snapClicked()));
|
||||
|
||||
ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
|
||||
ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
|
||||
ui->channelPowerMeter->setColorTheme(LevelMeterSignalDB::ColorGreenAndBlue);
|
||||
@ -356,7 +536,9 @@ void AMDemodGUI::displaySettings()
|
||||
|
||||
blockApplySettings(true);
|
||||
|
||||
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
|
||||
ui->frequencyMode->setCurrentIndex((int) m_settings.m_frequencyMode);
|
||||
on_frequencyMode_currentIndexChanged((int) m_settings.m_frequencyMode);
|
||||
displaySnap();
|
||||
|
||||
int displayValue = m_settings.m_rfBandwidth/100.0;
|
||||
ui->rfBW->setValue(displayValue);
|
||||
@ -459,6 +641,56 @@ void AMDemodGUI::samSSBSelect(const QPoint& p)
|
||||
}
|
||||
}
|
||||
|
||||
void AMDemodGUI::snapClicked()
|
||||
{
|
||||
if (m_settings.m_frequencyMode == AMDemodSettings::Offset) {
|
||||
m_settings.m_snap = false;
|
||||
} else {
|
||||
m_settings.m_snap = !m_settings.m_snap;
|
||||
}
|
||||
if (m_settings.m_snap) {
|
||||
applySnap();
|
||||
}
|
||||
displaySnap();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void AMDemodGUI::applySnap()
|
||||
{
|
||||
if (m_settings.m_frequencyMode == AMDemodSettings::Offset) {
|
||||
return;
|
||||
}
|
||||
|
||||
qint64 frequency = m_deviceCenterFrequency + m_settings.m_inputFrequencyOffset;
|
||||
if (m_settings.m_frequencyMode == AMDemodSettings::MediumWave)
|
||||
{
|
||||
frequency = (frequency / 1000) * 1000;
|
||||
}
|
||||
else if (m_settings.m_frequencyMode == AMDemodSettings::Airband25k)
|
||||
{
|
||||
frequency = (frequency / 25000) * 25000;
|
||||
}
|
||||
else if (m_settings.m_frequencyMode == AMDemodSettings::Airband8K)
|
||||
{
|
||||
frequency = std::round((frequency / 8333) * 8333.3);
|
||||
}
|
||||
m_settings.m_inputFrequencyOffset = frequency - m_deviceCenterFrequency;
|
||||
m_channelMarker.setCenterFrequency(m_settings.m_inputFrequencyOffset);
|
||||
}
|
||||
|
||||
void AMDemodGUI::displaySnap()
|
||||
{
|
||||
if (m_settings.m_snap)
|
||||
{
|
||||
ui->frequencyMode->setStyleSheet(QString("QComboBox{ background-color: %1; }")
|
||||
.arg(palette().highlight().color().darker(150).name()));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->frequencyMode->setStyleSheet("");
|
||||
}
|
||||
}
|
||||
|
||||
void AMDemodGUI::tick()
|
||||
{
|
||||
double magsqAvg, magsqPeak;
|
||||
@ -510,6 +742,7 @@ void AMDemodGUI::tick()
|
||||
|
||||
void AMDemodGUI::makeUIConnections()
|
||||
{
|
||||
QObject::connect(ui->frequencyMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &AMDemodGUI::on_frequencyMode_currentIndexChanged);
|
||||
QObject::connect(ui->deltaFrequency, &ValueDialZ::changed, this, &AMDemodGUI::on_deltaFrequency_changed);
|
||||
QObject::connect(ui->pll, &QToolButton::toggled, this, &AMDemodGUI::on_pll_toggled);
|
||||
QObject::connect(ui->ssb, &QToolButton::toggled, this, &AMDemodGUI::on_ssb_toggled);
|
||||
@ -524,4 +757,14 @@ void AMDemodGUI::makeUIConnections()
|
||||
void AMDemodGUI::updateAbsoluteCenterFrequency()
|
||||
{
|
||||
setStatusFrequency(m_deviceCenterFrequency + m_settings.m_inputFrequencyOffset);
|
||||
|
||||
if (m_invalidChannel && (m_settings.m_frequencyMode == AMDemodSettings::Airband8K)) {
|
||||
setStatusText("Invalid 8.33kHz channel");
|
||||
} else if ( (m_basebandSampleRate > 1)
|
||||
&& ( (m_settings.m_inputFrequencyOffset >= m_basebandSampleRate / 2)
|
||||
|| (m_settings.m_inputFrequencyOffset < -m_basebandSampleRate / 2))) {
|
||||
setStatusText("Frequency out of band");
|
||||
} else {
|
||||
setStatusText("");
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +68,8 @@ private:
|
||||
QIcon m_iconDSBUSB;
|
||||
QIcon m_iconDSBLSB;
|
||||
|
||||
bool m_invalidChannel;
|
||||
|
||||
explicit AMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = 0);
|
||||
virtual ~AMDemodGUI();
|
||||
|
||||
@ -77,11 +79,15 @@ private:
|
||||
bool handleMessage(const Message& message);
|
||||
void makeUIConnections();
|
||||
void updateAbsoluteCenterFrequency();
|
||||
void calcOffset();
|
||||
void applySnap();
|
||||
void displaySnap();
|
||||
|
||||
void leaveEvent(QEvent*);
|
||||
void enterEvent(EnterEventType*);
|
||||
|
||||
private slots:
|
||||
void on_frequencyMode_currentIndexChanged(int index);
|
||||
void on_deltaFrequency_changed(qint64 value);
|
||||
void on_pll_toggled(bool checked);
|
||||
void on_ssb_toggled(bool checked);
|
||||
@ -96,6 +102,7 @@ private slots:
|
||||
void handleInputMessages();
|
||||
void audioSelect(const QPoint& p);
|
||||
void samSSBSelect(const QPoint& p);
|
||||
void snapClicked();
|
||||
void tick();
|
||||
};
|
||||
|
||||
|
@ -82,16 +82,42 @@
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="deltaFrequencyLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="deltaFrequencyLabel">
|
||||
<widget class="QComboBox" name="frequencyMode">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<width>58</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Df</string>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Select frequency entry mode. Right click to snap makers to channel center</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Δf</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>MW</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>25k</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>8.33k</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -44,6 +44,9 @@ void AMDemodSettings::resetToDefaults()
|
||||
m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName;
|
||||
m_pll = false;
|
||||
m_syncAMOperation = SyncAMDSB;
|
||||
m_frequencyMode = Offset;
|
||||
m_frequency = 0;
|
||||
m_snap = false;
|
||||
m_streamIndex = 0;
|
||||
m_useReverseAPI = false;
|
||||
m_reverseAPIAddress = "127.0.0.1";
|
||||
@ -88,6 +91,9 @@ QByteArray AMDemodSettings::serialize() const
|
||||
s.writeBlob(21, m_geometryBytes);
|
||||
s.writeBool(22, m_hidden);
|
||||
s.writeBool(23, m_audioMute);
|
||||
s.writeS32(24, (int) m_frequencyMode);
|
||||
s.writeS64(25, m_frequency);
|
||||
s.writeBool(26, m_snap);
|
||||
|
||||
return s.final();
|
||||
}
|
||||
@ -157,6 +163,9 @@ bool AMDemodSettings::deserialize(const QByteArray& data)
|
||||
d.readBlob(21, &m_geometryBytes);
|
||||
d.readBool(22, &m_hidden, false);
|
||||
d.readBool(23, &m_audioMute);
|
||||
d.readS32(24, (int *) &m_frequencyMode, (int) Offset);
|
||||
d.readS64(25, &m_frequency);
|
||||
d.readBool(26, &m_snap, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -30,6 +30,12 @@ struct AMDemodSettings
|
||||
SyncAMUSB,
|
||||
SyncAMLSB
|
||||
};
|
||||
enum FrequencyMode {
|
||||
Offset,
|
||||
MediumWave,
|
||||
Airband25k,
|
||||
Airband8K
|
||||
};
|
||||
|
||||
qint32 m_inputFrequencyOffset;
|
||||
Real m_rfBandwidth;
|
||||
@ -44,6 +50,9 @@ struct AMDemodSettings
|
||||
QString m_audioDeviceName;
|
||||
bool m_pll;
|
||||
SyncAMOperation m_syncAMOperation;
|
||||
FrequencyMode m_frequencyMode;
|
||||
qint64 m_frequency;
|
||||
bool m_snap;
|
||||
int m_streamIndex; //!< MIMO channel. Not relevant when connected to SI (single Rx).
|
||||
bool m_useReverseAPI;
|
||||
QString m_reverseAPIAddress;
|
||||
|
@ -1,4 +1,4 @@
|
||||
<h1>AM demodulator plugin</h1>
|
||||
<h1>AM demodulator plugin</h1>
|
||||
|
||||
<h2>Introduction</h2>
|
||||
|
||||
@ -10,9 +10,25 @@ The top and bottom bars of the channel window are described [here](../../../sdrg
|
||||
|
||||
![AM Demodulator plugin GUI](../../../doc/img/AMDemod_plugin.png)
|
||||
|
||||
<h3>1: Frequency shift from center frequency of reception</h3>
|
||||
<h3>Channel frequency entry mode</h3>
|
||||
|
||||
Use the wheels to adjust the frequency shift in Hz from the center frequency of reception. Left click on a digit sets the cursor position at this digit. Right click on a digit sets all digits on the right to zero. This effectively floors value at the digit position. Wheels are moved with the mousewheel while pointing at the wheel or by selecting the wheel with the left mouse click and using the keyboard arrows. Pressing shift simultaneously moves digit by 5 and pressing control moves it by 2.
|
||||
Select from one of the following modes to determine how the channel center frequency is calculated:
|
||||
|
||||
* Δf - Specify an offset in Hz from device center frequency.
|
||||
* MW - Specify a LW/MW absolute frequency in kHz. Right click to snap channel marker to nearest 1kHz when dragged.
|
||||
* 25k - Specify absolute frequency in MHz. Right click to snap channel marker to 25kHz channels when dragged.
|
||||
* 8.33k - Specify airband 8.33kHz channel number. Right click to snap channel marker to 8.33kHz channels when dragged.
|
||||
|
||||
<h3>1: Channel Frequency</h3>
|
||||
|
||||
Specifies channel center frequency according to frequency entry mode:
|
||||
|
||||
* Δf - Offset in Hz from device center frequency;
|
||||
* MW - Absolute frequency in kHz.
|
||||
* 25k - Absolute frequency in MHz.
|
||||
* 8.33k - Airband 8.33kHz channel number.
|
||||
|
||||
Use the wheels to adjust the value. Left click on a digit sets the cursor position at this digit. Right click on a digit sets all digits on the right to zero. This effectively floors value at the digit position. Wheels are moved with the mousewheel while pointing at the wheel or by selecting the wheel with the left mouse click and using the keyboard arrows. Pressing shift simultaneously moves digit by 5 and pressing control moves it by 2.
|
||||
|
||||
<h3>2: PLL and synchronous AM</h2>
|
||||
|
||||
|
@ -136,6 +136,7 @@ ChannelGUI::ChannelGUI(QWidget *parent) :
|
||||
// m_statusLabel->setText("OK"); // for future use
|
||||
m_statusLabel->setFixedHeight(20);
|
||||
m_statusLabel->setMinimumWidth(20);
|
||||
m_statusLabel->setContentsMargins(10, 0, 0, 0); // Add space between statusFrequency and statusLabel
|
||||
m_statusLabel->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
|
||||
m_statusLabel->setToolTip("Channel status");
|
||||
|
||||
|
@ -637,7 +637,7 @@ void ValueDialZ::keyPressEvent(QKeyEvent* value)
|
||||
setValue(-m_value);
|
||||
update();
|
||||
}
|
||||
else if ((c >= QChar('0')) && (c <= QChar('9')) && (m_cursor > 0)) // digits
|
||||
else if ((c >= QChar('0')) && (c <= QChar('9')) && (m_cursor >= (m_positiveOnly ? 0 : 1))) // digits
|
||||
{
|
||||
if(m_animationState != 0) {
|
||||
m_value = m_valueNew;
|
||||
|
@ -37,6 +37,16 @@ AMDemodSettings:
|
||||
syncAMOperation:
|
||||
description: Synchronous AM sidebands mode (DSB, USB, LSB)
|
||||
type: integer
|
||||
frequencyMode:
|
||||
description: (0 for Offset, 1 for MW, 2 for 25k, 3 for 8.33k)
|
||||
type: integer
|
||||
frequency:
|
||||
description: Channel center frequency
|
||||
type: integer
|
||||
format: int64
|
||||
snap:
|
||||
description: Snap channel marker to channel center frequencies
|
||||
type: integer
|
||||
streamIndex:
|
||||
description: MIMO channel. Not relevant when connected to SI (single Rx).
|
||||
type: integer
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* 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 ---
|
||||
* 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: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
@ -52,6 +52,12 @@ SWGAMDemodSettings::SWGAMDemodSettings() {
|
||||
m_pll_isSet = false;
|
||||
sync_am_operation = 0;
|
||||
m_sync_am_operation_isSet = false;
|
||||
frequency_mode = 0;
|
||||
m_frequency_mode_isSet = false;
|
||||
frequency = 0L;
|
||||
m_frequency_isSet = false;
|
||||
snap = 0;
|
||||
m_snap_isSet = false;
|
||||
stream_index = 0;
|
||||
m_stream_index_isSet = false;
|
||||
use_reverse_api = 0;
|
||||
@ -100,6 +106,12 @@ SWGAMDemodSettings::init() {
|
||||
m_pll_isSet = false;
|
||||
sync_am_operation = 0;
|
||||
m_sync_am_operation_isSet = false;
|
||||
frequency_mode = 0;
|
||||
m_frequency_mode_isSet = false;
|
||||
frequency = 0L;
|
||||
m_frequency_isSet = false;
|
||||
snap = 0;
|
||||
m_snap_isSet = false;
|
||||
stream_index = 0;
|
||||
m_stream_index_isSet = false;
|
||||
use_reverse_api = 0;
|
||||
@ -128,26 +140,29 @@ SWGAMDemodSettings::cleanup() {
|
||||
|
||||
|
||||
|
||||
if(title != nullptr) {
|
||||
if(title != nullptr) {
|
||||
delete title;
|
||||
}
|
||||
if(audio_device_name != nullptr) {
|
||||
if(audio_device_name != nullptr) {
|
||||
delete audio_device_name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if(reverse_api_address != nullptr) {
|
||||
|
||||
|
||||
|
||||
if(reverse_api_address != nullptr) {
|
||||
delete reverse_api_address;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(channel_marker != nullptr) {
|
||||
if(channel_marker != nullptr) {
|
||||
delete channel_marker;
|
||||
}
|
||||
if(rollup_state != nullptr) {
|
||||
if(rollup_state != nullptr) {
|
||||
delete rollup_state;
|
||||
}
|
||||
}
|
||||
@ -164,45 +179,51 @@ SWGAMDemodSettings::fromJson(QString &json) {
|
||||
void
|
||||
SWGAMDemodSettings::fromJsonObject(QJsonObject &pJson) {
|
||||
::SWGSDRangel::setValue(&input_frequency_offset, pJson["inputFrequencyOffset"], "qint64", "");
|
||||
|
||||
|
||||
::SWGSDRangel::setValue(&rf_bandwidth, pJson["rfBandwidth"], "float", "");
|
||||
|
||||
|
||||
::SWGSDRangel::setValue(&af_bandwidth, pJson["afBandwidth"], "float", "");
|
||||
|
||||
|
||||
::SWGSDRangel::setValue(&squelch, pJson["squelch"], "float", "");
|
||||
|
||||
|
||||
::SWGSDRangel::setValue(&volume, pJson["volume"], "float", "");
|
||||
|
||||
|
||||
::SWGSDRangel::setValue(&audio_mute, pJson["audioMute"], "qint32", "");
|
||||
|
||||
|
||||
::SWGSDRangel::setValue(&bandpass_enable, pJson["bandpassEnable"], "qint32", "");
|
||||
|
||||
|
||||
::SWGSDRangel::setValue(&rgb_color, pJson["rgbColor"], "qint32", "");
|
||||
|
||||
|
||||
::SWGSDRangel::setValue(&title, pJson["title"], "QString", "QString");
|
||||
|
||||
|
||||
::SWGSDRangel::setValue(&audio_device_name, pJson["audioDeviceName"], "QString", "QString");
|
||||
|
||||
|
||||
::SWGSDRangel::setValue(&pll, pJson["pll"], "qint32", "");
|
||||
|
||||
|
||||
::SWGSDRangel::setValue(&sync_am_operation, pJson["syncAMOperation"], "qint32", "");
|
||||
|
||||
|
||||
::SWGSDRangel::setValue(&frequency_mode, pJson["frequencyMode"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&frequency, pJson["frequency"], "qint64", "");
|
||||
|
||||
::SWGSDRangel::setValue(&snap, pJson["snap"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&stream_index, pJson["streamIndex"], "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", "");
|
||||
|
||||
|
||||
::SWGSDRangel::setValue(&reverse_api_channel_index, pJson["reverseAPIChannelIndex"], "qint32", "");
|
||||
|
||||
|
||||
::SWGSDRangel::setValue(&channel_marker, pJson["channelMarker"], "SWGChannelMarker", "SWGChannelMarker");
|
||||
|
||||
|
||||
::SWGSDRangel::setValue(&rollup_state, pJson["rollupState"], "SWGRollupState", "SWGRollupState");
|
||||
|
||||
|
||||
}
|
||||
|
||||
QString
|
||||
@ -255,6 +276,15 @@ SWGAMDemodSettings::asJsonObject() {
|
||||
if(m_sync_am_operation_isSet){
|
||||
obj->insert("syncAMOperation", QJsonValue(sync_am_operation));
|
||||
}
|
||||
if(m_frequency_mode_isSet){
|
||||
obj->insert("frequencyMode", QJsonValue(frequency_mode));
|
||||
}
|
||||
if(m_frequency_isSet){
|
||||
obj->insert("frequency", QJsonValue(frequency));
|
||||
}
|
||||
if(m_snap_isSet){
|
||||
obj->insert("snap", QJsonValue(snap));
|
||||
}
|
||||
if(m_stream_index_isSet){
|
||||
obj->insert("streamIndex", QJsonValue(stream_index));
|
||||
}
|
||||
@ -403,6 +433,36 @@ SWGAMDemodSettings::setSyncAmOperation(qint32 sync_am_operation) {
|
||||
this->m_sync_am_operation_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGAMDemodSettings::getFrequencyMode() {
|
||||
return frequency_mode;
|
||||
}
|
||||
void
|
||||
SWGAMDemodSettings::setFrequencyMode(qint32 frequency_mode) {
|
||||
this->frequency_mode = frequency_mode;
|
||||
this->m_frequency_mode_isSet = true;
|
||||
}
|
||||
|
||||
qint64
|
||||
SWGAMDemodSettings::getFrequency() {
|
||||
return frequency;
|
||||
}
|
||||
void
|
||||
SWGAMDemodSettings::setFrequency(qint64 frequency) {
|
||||
this->frequency = frequency;
|
||||
this->m_frequency_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGAMDemodSettings::getSnap() {
|
||||
return snap;
|
||||
}
|
||||
void
|
||||
SWGAMDemodSettings::setSnap(qint32 snap) {
|
||||
this->snap = snap;
|
||||
this->m_snap_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGAMDemodSettings::getStreamIndex() {
|
||||
return stream_index;
|
||||
@ -524,6 +584,15 @@ SWGAMDemodSettings::isSet(){
|
||||
if(m_sync_am_operation_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_frequency_mode_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_frequency_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_snap_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_stream_index_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
@ -552,4 +621,3 @@ SWGAMDemodSettings::isSet(){
|
||||
return isObjectUpdated;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* 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 ---
|
||||
* 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: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
@ -80,6 +80,15 @@ public:
|
||||
qint32 getSyncAmOperation();
|
||||
void setSyncAmOperation(qint32 sync_am_operation);
|
||||
|
||||
qint32 getFrequencyMode();
|
||||
void setFrequencyMode(qint32 frequency_mode);
|
||||
|
||||
qint64 getFrequency();
|
||||
void setFrequency(qint64 frequency);
|
||||
|
||||
qint32 getSnap();
|
||||
void setSnap(qint32 snap);
|
||||
|
||||
qint32 getStreamIndex();
|
||||
void setStreamIndex(qint32 stream_index);
|
||||
|
||||
@ -144,6 +153,15 @@ private:
|
||||
qint32 sync_am_operation;
|
||||
bool m_sync_am_operation_isSet;
|
||||
|
||||
qint32 frequency_mode;
|
||||
bool m_frequency_mode_isSet;
|
||||
|
||||
qint64 frequency;
|
||||
bool m_frequency_isSet;
|
||||
|
||||
qint32 snap;
|
||||
bool m_snap_isSet;
|
||||
|
||||
qint32 stream_index;
|
||||
bool m_stream_index_isSet;
|
||||
|
||||
@ -172,4 +190,4 @@ private:
|
||||
|
||||
}
|
||||
|
||||
#endif /* SWGAMDemodSettings_H_ */
|
||||
#endif /* SWGAMDemodSettings_H_ */
|
Loading…
Reference in New Issue
Block a user