1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-09-27 15:26:33 -04:00

Local Sink: added GUI controls and implemented gain stage

This commit is contained in:
f4exb 2022-12-05 14:18:31 +01:00
parent 2754e3ea5e
commit 4d1ab5d413
9 changed files with 480 additions and 11 deletions

View File

@ -320,6 +320,8 @@ void LocalSink::applySettings(const LocalSinkSettings& settings, bool force)
<< "m_localDeviceIndex: " << settings.m_localDeviceIndex
<< "m_streamIndex: " << settings.m_streamIndex
<< "m_play:" << settings.m_play
<< "m_dsp:" << settings.m_dsp
<< "m_gaindB:" << settings.m_gaindB
<< "force: " << force;
QList<QString> reverseAPIKeys;

View File

@ -173,7 +173,7 @@ void LocalSinkBaseband::applySettings(const LocalSinkSettings& settings, bool fo
m_sink.setSampleRate(getChannelSampleRate());
}
//m_source.applySettings(settings, force);
m_sink.applySettings(settings, force);
m_settings = settings;
}

View File

@ -193,6 +193,8 @@ void LocalSinkGUI::displaySettings()
ui->localDevicePlay->setChecked(m_settings.m_play);
ui->decimationFactor->setCurrentIndex(m_settings.m_log2Decim);
ui->dsp->setChecked(m_settings.m_dsp);
ui->gainText->setText(tr("%1").arg(m_settings.m_gaindB));
applyDecimation();
updateIndexLabel();
@ -348,6 +350,19 @@ void LocalSinkGUI::on_localDevicePlay_toggled(bool checked)
applySettings();
}
void LocalSinkGUI::on_dsp_toggled(bool checked)
{
m_settings.m_dsp = checked;
applySettings();
}
void LocalSinkGUI::on_gain_valueChanged(int value)
{
m_settings.m_gaindB = value;
ui->gainText->setText(tr("%1").arg(value));
applySettings();
}
void LocalSinkGUI::applyDecimation()
{
uint32_t maxHash = 1;
@ -387,6 +402,8 @@ void LocalSinkGUI::makeUIConnections()
QObject::connect(ui->position, &QSlider::valueChanged, this, &LocalSinkGUI::on_position_valueChanged);
QObject::connect(ui->localDevice, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &LocalSinkGUI::on_localDevice_currentIndexChanged);
QObject::connect(ui->localDevicePlay, &ButtonSwitch::toggled, this, &LocalSinkGUI::on_localDevicePlay_toggled);
QObject::connect(ui->dsp, &ButtonSwitch::toggled, this, &LocalSinkGUI::on_dsp_toggled);
QObject::connect(ui->gain, &QSlider::valueChanged, this, &LocalSinkGUI::on_gain_valueChanged);
}
void LocalSinkGUI::updateAbsoluteCenterFrequency()

View File

@ -104,6 +104,8 @@ private slots:
void on_position_valueChanged(int value);
void on_localDevice_currentIndexChanged(int index);
void on_localDevicePlay_toggled(bool checked);
void on_dsp_toggled(bool checked);
void on_gain_valueChanged(int value);
void onWidgetRolled(QWidget* widget, bool rollDown);
void onMenuDialogCalled(const QPoint& p);
void tick();

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>414</width>
<height>406</height>
<width>452</width>
<height>467</height>
</rect>
</property>
<property name="sizePolicy">
@ -34,10 +34,10 @@
<widget class="QWidget" name="settingsContainer" native="true">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>401</width>
<height>91</height>
<x>1</x>
<y>1</y>
<width>451</width>
<height>141</height>
</rect>
</property>
<property name="minimumSize">
@ -66,7 +66,7 @@
<number>2</number>
</property>
<item>
<layout class="QVBoxLayout" name="decimationLayer">
<layout class="QVBoxLayout" name="decimationLayout">
<property name="spacing">
<number>3</number>
</property>
@ -290,6 +290,215 @@
</property>
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="dsp">
<property name="text">
<string>DSP</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="gainLabel">
<property name="text">
<string>G</string>
</property>
</widget>
</item>
<item>
<widget class="QDial" name="gain">
<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>Gain in dB</string>
</property>
<property name="minimum">
<number>-10</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="gainText">
<property name="minimumSize">
<size>
<width>26</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Gain in dB</string>
</property>
<property name="text">
<string>100</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="fft">
<property name="text">
<string>FFT</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="fftSize">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<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>FFT size</string>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<item>
<property name="text">
<string>64</string>
</property>
</item>
<item>
<property name="text">
<string>128</string>
</property>
</item>
<item>
<property name="text">
<string>256</string>
</property>
</item>
<item>
<property name="text">
<string>512</string>
</property>
</item>
<item>
<property name="text">
<string>1k</string>
</property>
</item>
<item>
<property name="text">
<string>2k</string>
</property>
</item>
<item>
<property name="text">
<string>4k</string>
</property>
</item>
<item>
<property name="text">
<string>8k</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QComboBox" name="fftWindow">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>FFT filter window function</string>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<item>
<property name="text">
<string>Bart</string>
</property>
</item>
<item>
<property name="text">
<string>B-H</string>
</property>
</item>
<item>
<property name="text">
<string>FT</string>
</property>
</item>
<item>
<property name="text">
<string>Ham</string>
</property>
</item>
<item>
<property name="text">
<string>Han</string>
</property>
</item>
<item>
<property name="text">
<string>Rec</string>
</property>
</item>
<item>
<property name="text">
<string>Kai</string>
</property>
</item>
<item>
<property name="text">
<string>Black</string>
</property>
</item>
<item>
<property name="text">
<string>B-H7</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@ -305,13 +514,203 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="fftLayout">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Band</string>
</property>
</widget>
</item>
<item>
<widget class="QDial" name="bandIndex">
<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>FFT band index</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>9</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="bandIndexText">
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>FFT band index</string>
</property>
<property name="text">
<string>00</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="f1Label">
<property name="text">
<string>f1</string>
</property>
</widget>
</item>
<item>
<widget class="QDial" name="f1Bin">
<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>Frequency limit #1 bin</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>1023</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="f1Text">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Frequency limit #1 frequency</string>
</property>
<property name="text">
<string>100.00k</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</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="f2Label">
<property name="text">
<string>f2</string>
</property>
</widget>
</item>
<item>
<widget class="QDial" name="f2Bin">
<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>Frequency limit #2 bin</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>1023</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="f2Text">
<property name="minimumSize">
<size>
<width>50</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Frequency limit #2 frequency</string>
</property>
<property name="text">
<string>100.00k</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>
</layout>
</widget>
<widget class="QWidget" name="spectrumContainer" native="true">
<property name="geometry">
<rect>
<x>10</x>
<y>110</y>
<y>160</y>
<width>218</width>
<height>284</height>
</rect>

View File

@ -38,6 +38,8 @@ void LocalSinkSettings::resetToDefaults()
m_channelMarker = nullptr;
m_rollupState = nullptr;
m_play = false;
m_dsp = false;
m_gaindB = 0;
m_streamIndex = 0;
m_useReverseAPI = false;
m_reverseAPIAddress = "127.0.0.1";
@ -75,6 +77,12 @@ QByteArray LocalSinkSettings::serialize() const
s.writeS32(16, m_workspaceIndex);
s.writeBlob(17, m_geometryBytes);
s.writeBool(18, m_hidden);
s.writeBool(19, m_dsp);
s.writeS32(20, m_gaindB);
if (m_spectrumGUI) {
s.writeBlob(21, m_spectrumGUI->serialize());
}
return s.final();
}
@ -133,6 +141,14 @@ bool LocalSinkSettings::deserialize(const QByteArray& data)
d.readS32(16, &m_workspaceIndex, 0);
d.readBlob(17, &m_geometryBytes);
d.readBool(18, &m_hidden, false);
d.readBool(19, &m_dsp, false);
d.readS32(20, &m_gaindB, 0);
if (m_spectrumGUI)
{
d.readBlob(21, &bytetmp);
m_spectrumGUI->deserialize(bytetmp);
}
return true;
}

View File

@ -31,6 +31,8 @@ struct LocalSinkSettings
uint32_t m_log2Decim;
uint32_t m_filterChainHash;
bool m_play;
bool m_dsp;
int m_gaindB;
int m_streamIndex; //!< MIMO channel. Not relevant when connected to SI (single Rx).
bool m_useReverseAPI;
QString m_reverseAPIAddress;

View File

@ -22,6 +22,7 @@
#include "dsp/devicesamplesource.h"
#include "dsp/hbfilterchainconverter.h"
#include "dsp/spectrumvis.h"
#include "util/db.h"
#include "localsinkworker.h"
#include "localsinksink.h"
@ -31,6 +32,7 @@ LocalSinkSink::LocalSinkSink() :
m_sinkWorker(nullptr),
m_spectrumSink(nullptr),
m_running(false),
m_gain(1.0),
m_centerFrequency(0),
m_frequencyOffset(0),
m_sampleRate(48000),
@ -46,8 +48,32 @@ LocalSinkSink::~LocalSinkSink()
void LocalSinkSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end)
{
if (m_running && m_deviceSource) {
m_deviceSource->getSampleFifo()->write(begin, end);
if (m_settings.m_dsp && (m_settings.m_gaindB != 0))
{
m_spectrumBuffer.resize(end - begin);
std::transform(
begin,
end,
m_spectrumBuffer.begin(),
[this](const Sample& s) -> Sample {
Complex c(s.real(), s.imag());
c *= m_gain;
return Sample(c.real(), c.imag());
}
);
if (m_running && m_deviceSource) {
m_deviceSource->getSampleFifo()->write(m_spectrumBuffer.begin(), m_spectrumBuffer.end());
}
if (m_spectrumSink) {
m_spectrumSink->feed(m_spectrumBuffer.begin(), m_spectrumBuffer.end(), false);
}
m_spectrumBuffer.clear();
}
else
{
if (m_running && m_deviceSource) {
m_deviceSource->getSampleFifo()->write(begin, end);
}
}
if (m_spectrumSink) {
@ -129,6 +155,10 @@ void LocalSinkSink::applySettings(const LocalSinkSettings& settings, bool force)
<< " m_streamIndex: " << settings.m_streamIndex
<< " force: " << force;
if ((settings.m_gaindB != m_settings.m_gaindB) || force) {
m_gain = CalcDb::powerFromdB(settings.m_gaindB/2.0); // Amplitude gain
}
m_settings = settings;
}

View File

@ -53,6 +53,7 @@ private:
SpectrumVis* m_spectrumSink;
SampleVector m_spectrumBuffer;
bool m_running;
float m_gain; //!< Amplitude gain
uint64_t m_centerFrequency;
int64_t m_frequencyOffset;