1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-16 13:21:50 -05:00

UDPSink plugin: interim state (1)

This commit is contained in:
f4exb 2017-08-14 10:59:05 +02:00
parent 16f1f44c64
commit 3e5c6f62b1
4 changed files with 135 additions and 15 deletions

View File

@ -27,6 +27,9 @@ UDPSink::UDPSink(MessageQueue* uiMessageQueue, UDPSinkGUI* udpSinkGUI, BasebandS
m_spectrum(spectrum), m_spectrum(spectrum),
m_settingsMutex(QMutex::Recursive) m_settingsMutex(QMutex::Recursive)
{ {
setObjectName("UDPSink");
apply(true);
} }
UDPSink::~UDPSink() UDPSink::~UDPSink()
@ -43,8 +46,48 @@ void UDPSink::stop()
void UDPSink::pull(Sample& sample) void UDPSink::pull(Sample& sample)
{ {
if (m_running.m_channelMute)
{
sample.m_real = 0.0f; sample.m_real = 0.0f;
sample.m_imag = 0.0f; sample.m_imag = 0.0f;
return;
}
Complex ci;
m_settingsMutex.lock();
if (m_interpolatorDistance > 1.0f) // decimate
{
modulateSample();
while (!m_interpolator.decimate(&m_interpolatorDistanceRemain, m_modSample, &ci))
{
modulateSample();
}
}
else
{
if (m_interpolator.interpolate(&m_interpolatorDistanceRemain, m_modSample, &ci))
{
modulateSample();
}
}
m_interpolatorDistanceRemain += m_interpolatorDistance;
ci *= m_carrierNco.nextIQ(); // shift to carrier frequency
m_settingsMutex.unlock();
sample.m_real = (FixReal) ci.real();
sample.m_imag = (FixReal) ci.imag();
}
void UDPSink::modulateSample()
{
m_modSample.real(0.0f); // TODO
m_modSample.imag(0.0f);
} }
bool UDPSink::handleMessage(const Message& cmd) bool UDPSink::handleMessage(const Message& cmd)
@ -82,9 +125,19 @@ bool UDPSink::handleMessage(const Message& cmd)
m_config.m_fmDeviation = cfg.getFMDeviation(); m_config.m_fmDeviation = cfg.getFMDeviation();
m_config.m_udpAddressStr = cfg.getUDPAddress(); m_config.m_udpAddressStr = cfg.getUDPAddress();
m_config.m_udpPort = cfg.getUDPPort(); m_config.m_udpPort = cfg.getUDPPort();
m_config.m_channelMute = cfg.getChannelMute();
m_settingsMutex.unlock(); m_settingsMutex.unlock();
qDebug() << "UDPSink::handleMessage: MsgUDPSinkConfigure:"
<< " m_sampleFormat: " << m_config.m_sampleFormat
<< " m_inputSampleRate: " << m_config.m_inputSampleRate
<< " m_rfBandwidth: " << m_config.m_rfBandwidth
<< " m_fmDeviation: " << m_config.m_fmDeviation
<< " m_udpAddressStr: " << m_config.m_udpAddressStr
<< " m_udpPort: " << m_config.m_udpPort
<< " m_channelMute: " << m_config.m_channelMute;
return true; return true;
} }
else else
@ -99,14 +152,40 @@ void UDPSink::configure(MessageQueue* messageQueue,
Real rfBandwidth, Real rfBandwidth,
int fmDeviation, int fmDeviation,
QString& udpAddress, QString& udpAddress,
int udpPort) int udpPort,
bool channelMute)
{ {
Message* cmd = MsgUDPSinkConfigure::create(sampleFormat, Message* cmd = MsgUDPSinkConfigure::create(sampleFormat,
outputSampleRate, outputSampleRate,
rfBandwidth, rfBandwidth,
fmDeviation, fmDeviation,
udpAddress, udpAddress,
udpPort); udpPort,
channelMute);
messageQueue->push(cmd); messageQueue->push(cmd);
} }
void UDPSink::apply(bool force)
{
if ((m_config.m_inputFrequencyOffset != m_running.m_inputFrequencyOffset) ||
(m_config.m_outputSampleRate != m_running.m_outputSampleRate) || force)
{
m_settingsMutex.lock();
m_carrierNco.setFreq(m_config.m_inputFrequencyOffset, m_config.m_outputSampleRate);
m_settingsMutex.unlock();
}
if((m_config.m_outputSampleRate != m_running.m_outputSampleRate) ||
(m_config.m_rfBandwidth != m_running.m_rfBandwidth) ||
(m_config.m_inputSampleRate != m_running.m_inputSampleRate) || force)
{
m_settingsMutex.lock();
m_interpolatorDistanceRemain = 0;
m_interpolatorConsumed = false;
m_interpolatorDistance = (Real) m_config.m_inputSampleRate / (Real) m_config.m_outputSampleRate;
m_interpolator.create(48, m_config.m_inputSampleRate, m_config.m_rfBandwidth / 2.2, 3.0);
m_settingsMutex.unlock();
}
m_running = m_config;
}

View File

@ -21,6 +21,8 @@
#include "dsp/basebandsamplesource.h" #include "dsp/basebandsamplesource.h"
#include "dsp/basebandsamplesink.h" #include "dsp/basebandsamplesink.h"
#include "dsp/interpolator.h"
#include "dsp/nco.h"
#include "util/message.h" #include "util/message.h"
class UDPSinkGUI; class UDPSinkGUI;
@ -55,7 +57,8 @@ public:
Real rfBandwidth, Real rfBandwidth,
int fmDeviation, int fmDeviation,
QString& udpAddress, QString& udpAddress,
int udpPort); int udpPort,
bool channelMute);
private: private:
class MsgUDPSinkConfigure : public Message { class MsgUDPSinkConfigure : public Message {
@ -68,6 +71,7 @@ private:
int getFMDeviation() const { return m_fmDeviation; } int getFMDeviation() const { return m_fmDeviation; }
const QString& getUDPAddress() const { return m_udpAddress; } const QString& getUDPAddress() const { return m_udpAddress; }
int getUDPPort() const { return m_udpPort; } int getUDPPort() const { return m_udpPort; }
bool getChannelMute() const { return m_channelMute; }
static MsgUDPSinkConfigure* create(SampleFormat static MsgUDPSinkConfigure* create(SampleFormat
sampleFormat, sampleFormat,
@ -75,14 +79,16 @@ private:
Real rfBandwidth, Real rfBandwidth,
int fmDeviation, int fmDeviation,
QString& udpAddress, QString& udpAddress,
int udpPort) int udpPort,
bool channelMute)
{ {
return new MsgUDPSinkConfigure(sampleFormat, return new MsgUDPSinkConfigure(sampleFormat,
inputSampleRate, inputSampleRate,
rfBandwidth, rfBandwidth,
fmDeviation, fmDeviation,
udpAddress, udpAddress,
udpPort); udpPort,
channelMute);
} }
private: private:
@ -92,20 +98,23 @@ private:
int m_fmDeviation; int m_fmDeviation;
QString m_udpAddress; QString m_udpAddress;
int m_udpPort; int m_udpPort;
bool m_channelMute;
MsgUDPSinkConfigure(SampleFormat sampleFormat, MsgUDPSinkConfigure(SampleFormat sampleFormat,
Real inputSampleRate, Real inputSampleRate,
Real rfBandwidth, Real rfBandwidth,
int fmDeviation, int fmDeviation,
QString& udpAddress, QString& udpAddress,
int udpPort) : int udpPort,
bool channelMute) :
Message(), Message(),
m_sampleFormat(sampleFormat), m_sampleFormat(sampleFormat),
m_inputSampleRate(inputSampleRate), m_inputSampleRate(inputSampleRate),
m_rfBandwidth(rfBandwidth), m_rfBandwidth(rfBandwidth),
m_fmDeviation(fmDeviation), m_fmDeviation(fmDeviation),
m_udpAddress(udpAddress), m_udpAddress(udpAddress),
m_udpPort(udpPort) m_udpPort(udpPort),
m_channelMute(channelMute)
{ } { }
}; };
@ -117,18 +126,20 @@ private:
qint64 m_inputFrequencyOffset; qint64 m_inputFrequencyOffset;
Real m_rfBandwidth; Real m_rfBandwidth;
int m_fmDeviation; int m_fmDeviation;
bool m_channelMute;
QString m_udpAddressStr; QString m_udpAddressStr;
quint16 m_udpPort; quint16 m_udpPort;
Config() : Config() :
m_basebandSampleRate(0), m_basebandSampleRate(48000),
m_outputSampleRate(0), m_outputSampleRate(48000),
m_sampleFormat(0), m_sampleFormat(0),
m_inputSampleRate(0), m_inputSampleRate(48000),
m_inputFrequencyOffset(0), m_inputFrequencyOffset(0),
m_rfBandwidth(0), m_rfBandwidth(12500),
m_fmDeviation(0), m_fmDeviation(1.0),
m_channelMute(false),
m_udpAddressStr("127.0.0.1"), m_udpAddressStr("127.0.0.1"),
m_udpPort(9999) m_udpPort(9999)
{} {}
@ -137,11 +148,22 @@ private:
Config m_config; Config m_config;
Config m_running; Config m_running;
NCO m_carrierNco;
Complex m_modSample;
MessageQueue* m_uiMessageQueue; MessageQueue* m_uiMessageQueue;
UDPSinkGUI* m_udpSinkGUI; UDPSinkGUI* m_udpSinkGUI;
BasebandSampleSink* m_spectrum; BasebandSampleSink* m_spectrum;
Interpolator m_interpolator;
Real m_interpolatorDistance;
Real m_interpolatorDistanceRemain;
bool m_interpolatorConsumed;
QMutex m_settingsMutex; QMutex m_settingsMutex;
void apply(bool force);
void modulateSample();
}; };

View File

@ -367,7 +367,8 @@ void UDPSinkGUI::applySettings()
rfBandwidth, rfBandwidth,
fmDeviation, fmDeviation,
m_udpAddress, m_udpAddress,
udpPort); udpPort,
ui->channelMute->isChecked());
ui->applyBtn->setEnabled(false); ui->applyBtn->setEnabled(false);
} }

View File

@ -157,6 +157,24 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QToolButton" name="channelMute">
<property name="toolTip">
<string>Mute/Unmute channel</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrbase/resources/res.qrc">
<normaloff>:/txon.png</normaloff>
<normalon>:/txoff.png</normalon>:/txon.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item row="1" column="2"> <item row="1" column="2">