1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-30 03:38:55 -05:00

DSD decoder: put UDP sink for audio in place

This commit is contained in:
f4exb 2017-08-24 08:46:14 +02:00
parent 614021f9a0
commit 3b5fe0170f
5 changed files with 105 additions and 28 deletions

View File

@ -25,11 +25,13 @@
#include "audio/audiooutput.h" #include "audio/audiooutput.h"
#include "dsp/pidcontroller.h" #include "dsp/pidcontroller.h"
#include "dsp/dspengine.h" #include "dsp/dspengine.h"
#include "../../channelrx/demoddsd/dsddemodgui.h" #include "dsddemodgui.h"
MESSAGE_CLASS_DEFINITION(DSDDemod::MsgConfigureDSDDemod, Message) MESSAGE_CLASS_DEFINITION(DSDDemod::MsgConfigureDSDDemod, Message)
MESSAGE_CLASS_DEFINITION(DSDDemod::MsgConfigureMyPosition, Message) MESSAGE_CLASS_DEFINITION(DSDDemod::MsgConfigureMyPosition, Message)
const int DSDDemod::m_udpBlockSize = 512;
DSDDemod::DSDDemod(BasebandSampleSink* sampleSink) : DSDDemod::DSDDemod(BasebandSampleSink* sampleSink) :
m_sampleCount(0), m_sampleCount(0),
m_squelchCount(0), m_squelchCount(0),
@ -74,10 +76,13 @@ DSDDemod::DSDDemod(BasebandSampleSink* sampleSink) :
DSPEngine::instance()->addAudioSink(&m_audioFifo1); DSPEngine::instance()->addAudioSink(&m_audioFifo1);
DSPEngine::instance()->addAudioSink(&m_audioFifo2); DSPEngine::instance()->addAudioSink(&m_audioFifo2);
m_udpBufferMono = new UDPSink<FixReal>(this, m_udpBlockSize, m_config.m_udpPort);
} }
DSDDemod::~DSDDemod() DSDDemod::~DSDDemod()
{ {
delete m_udpBufferMono;
delete[] m_sampleBuffer; delete[] m_sampleBuffer;
DSPEngine::instance()->removeAudioSink(&m_audioFifo1); DSPEngine::instance()->removeAudioSink(&m_audioFifo1);
DSPEngine::instance()->removeAudioSink(&m_audioFifo2); DSPEngine::instance()->removeAudioSink(&m_audioFifo2);
@ -97,7 +102,11 @@ void DSDDemod::configure(MessageQueue* messageQueue,
bool slot1On, bool slot1On,
bool slot2On, bool slot2On,
bool tdmaStereo, bool tdmaStereo,
bool pllLock) bool pllLock,
bool udpCopyAudio,
const QString& udpAddress,
quint16 udpPort,
bool force)
{ {
Message* cmd = MsgConfigureDSDDemod::create(rfBandwidth, Message* cmd = MsgConfigureDSDDemod::create(rfBandwidth,
demodGain, demodGain,
@ -112,7 +121,11 @@ void DSDDemod::configure(MessageQueue* messageQueue,
slot1On, slot1On,
slot2On, slot2On,
tdmaStereo, tdmaStereo,
pllLock); pllLock,
udpCopyAudio,
udpAddress,
udpPort,
force);
messageQueue->push(cmd); messageQueue->push(cmd);
} }
@ -367,6 +380,9 @@ bool DSDDemod::handleMessage(const Message& cmd)
m_config.m_slot2On = cfg.getSlot2On(); m_config.m_slot2On = cfg.getSlot2On();
m_config.m_tdmaStereo = cfg.getTDMAStereo(); m_config.m_tdmaStereo = cfg.getTDMAStereo();
m_config.m_pllLock = cfg.getPLLLock(); m_config.m_pllLock = cfg.getPLLLock();
m_config.m_udpCopyAudio = cfg.getUDPCopyAudio();
m_config.m_udpAddress = cfg.getUDPAddress();
m_config.m_udpPort = cfg.getUDPPort();
apply(); apply();
@ -383,7 +399,10 @@ bool DSDDemod::handleMessage(const Message& cmd)
<< " m_slot1On: " << m_config.m_slot1On << " m_slot1On: " << m_config.m_slot1On
<< " m_slot2On: " << m_config.m_slot2On << " m_slot2On: " << m_config.m_slot2On
<< " m_tdmaStereo: " << m_config.m_tdmaStereo << " m_tdmaStereo: " << m_config.m_tdmaStereo
<< " m_pllLock: " << m_config.m_pllLock; << " m_pllLock: " << m_config.m_pllLock
<< " m_udpCopyAudio: " << m_config.m_udpCopyAudio
<< " m_udpAddress: " << m_config.m_udpAddress
<< " m_udpPort: " << m_config.m_udpPort;
return true; return true;
} }
@ -399,16 +418,16 @@ bool DSDDemod::handleMessage(const Message& cmd)
} }
} }
void DSDDemod::apply() void DSDDemod::apply(bool force)
{ {
if ((m_config.m_inputFrequencyOffset != m_running.m_inputFrequencyOffset) || if ((m_config.m_inputFrequencyOffset != m_running.m_inputFrequencyOffset) ||
(m_config.m_inputSampleRate != m_running.m_inputSampleRate)) (m_config.m_inputSampleRate != m_running.m_inputSampleRate) || force)
{ {
m_nco.setFreq(-m_config.m_inputFrequencyOffset, m_config.m_inputSampleRate); m_nco.setFreq(-m_config.m_inputFrequencyOffset, m_config.m_inputSampleRate);
} }
if ((m_config.m_inputSampleRate != m_running.m_inputSampleRate) || if ((m_config.m_inputSampleRate != m_running.m_inputSampleRate) ||
(m_config.m_rfBandwidth != m_running.m_rfBandwidth)) (m_config.m_rfBandwidth != m_running.m_rfBandwidth) || force)
{ {
m_settingsMutex.lock(); m_settingsMutex.lock();
m_interpolator.create(16, m_config.m_inputSampleRate, (m_config.m_rfBandwidth * 100) / 2.2); m_interpolator.create(16, m_config.m_inputSampleRate, (m_config.m_rfBandwidth * 100) / 2.2);
@ -418,49 +437,56 @@ void DSDDemod::apply()
m_settingsMutex.unlock(); m_settingsMutex.unlock();
} }
if (m_config.m_fmDeviation != m_running.m_fmDeviation) if ((m_config.m_fmDeviation != m_running.m_fmDeviation) || force)
{ {
m_phaseDiscri.setFMScaling((float) m_config.m_rfBandwidth / (float) m_config.m_fmDeviation); m_phaseDiscri.setFMScaling((float) m_config.m_rfBandwidth / (float) m_config.m_fmDeviation);
} }
if (m_config.m_squelchGate != m_running.m_squelchGate) if ((m_config.m_squelchGate != m_running.m_squelchGate) || force)
{ {
m_squelchGate = 480 * m_config.m_squelchGate; // gate is given in 10s of ms at 48000 Hz audio sample rate m_squelchGate = 480 * m_config.m_squelchGate; // gate is given in 10s of ms at 48000 Hz audio sample rate
m_squelchCount = 0; // reset squelch open counter m_squelchCount = 0; // reset squelch open counter
} }
if (m_config.m_squelch != m_running.m_squelch) if ((m_config.m_squelch != m_running.m_squelch) || force)
{ {
// input is a value in tenths of dB // input is a value in tenths of dB
m_squelchLevel = std::pow(10.0, m_config.m_squelch / 100.0); m_squelchLevel = std::pow(10.0, m_config.m_squelch / 100.0);
//m_squelchLevel *= m_squelchLevel; //m_squelchLevel *= m_squelchLevel;
} }
if (m_config.m_volume != m_running.m_volume) if ((m_config.m_volume != m_running.m_volume) || force)
{ {
m_dsdDecoder.setAudioGain(m_config.m_volume / 10.0f); m_dsdDecoder.setAudioGain(m_config.m_volume / 10.0f);
} }
if (m_config.m_baudRate != m_running.m_baudRate) if ((m_config.m_baudRate != m_running.m_baudRate) || force)
{ {
m_dsdDecoder.setBaudRate(m_config.m_baudRate); m_dsdDecoder.setBaudRate(m_config.m_baudRate);
} }
if (m_config.m_enableCosineFiltering != m_running.m_enableCosineFiltering) if ((m_config.m_enableCosineFiltering != m_running.m_enableCosineFiltering) || force)
{ {
m_dsdDecoder.enableCosineFiltering(m_config.m_enableCosineFiltering); m_dsdDecoder.enableCosineFiltering(m_config.m_enableCosineFiltering);
} }
if (m_config.m_tdmaStereo != m_running.m_tdmaStereo) if ((m_config.m_tdmaStereo != m_running.m_tdmaStereo) || force)
{ {
m_dsdDecoder.setTDMAStereo(m_config.m_tdmaStereo); m_dsdDecoder.setTDMAStereo(m_config.m_tdmaStereo);
} }
if (m_config.m_pllLock != m_running.m_pllLock) if ((m_config.m_pllLock != m_running.m_pllLock) || force)
{ {
m_dsdDecoder.setSymbolPLLLock(m_config.m_pllLock); m_dsdDecoder.setSymbolPLLLock(m_config.m_pllLock);
} }
if ((m_config.m_udpAddress != m_running.m_udpAddress)
|| (m_config.m_udpPort != m_running.m_udpPort) || force)
{
m_udpBufferMono->setAddress(m_config.m_udpAddress);
m_udpBufferMono->setPort(m_config.m_udpPort);
}
m_running.m_inputSampleRate = m_config.m_inputSampleRate; m_running.m_inputSampleRate = m_config.m_inputSampleRate;
m_running.m_inputFrequencyOffset = m_config.m_inputFrequencyOffset; m_running.m_inputFrequencyOffset = m_config.m_inputFrequencyOffset;
m_running.m_rfBandwidth = m_config.m_rfBandwidth; m_running.m_rfBandwidth = m_config.m_rfBandwidth;

View File

@ -31,8 +31,9 @@
#include "dsp/afsquelch.h" #include "dsp/afsquelch.h"
#include "audio/audiofifo.h" #include "audio/audiofifo.h"
#include "util/message.h" #include "util/message.h"
#include "util/udpsink.h"
#include "../../channelrx/demoddsd/dsddecoder.h" #include "dsddecoder.h"
class DSDDemodGUI; class DSDDemodGUI;
@ -55,7 +56,11 @@ public:
bool slot1On, bool slot1On,
bool slot2On, bool slot2On,
bool tdmaStereo, bool tdmaStereo,
bool pllLock); bool pllLock,
bool udpCopyAudio,
const QString& udpAddress,
quint16 udpPort,
bool force);
void configureMyPosition(MessageQueue* messageQueue, float myLatitude, float myLongitude); void configureMyPosition(MessageQueue* messageQueue, float myLatitude, float myLongitude);
@ -126,6 +131,9 @@ private:
bool getSlot2On() const { return m_slot2On; } bool getSlot2On() const { return m_slot2On; }
bool getTDMAStereo() const { return m_tdmaStereo; } bool getTDMAStereo() const { return m_tdmaStereo; }
bool getPLLLock() const { return m_pllLock; } bool getPLLLock() const { return m_pllLock; }
bool getUDPCopyAudio() const { return m_udpCopyAudio; }
const QString& getUDPAddress() const { return m_udpAddress; }
quint16 getUDPPort() const { return m_udpPort; }
static MsgConfigureDSDDemod* create(int rfBandwidth, static MsgConfigureDSDDemod* create(int rfBandwidth,
int demodGain, int demodGain,
@ -140,7 +148,11 @@ private:
bool slot1On, bool slot1On,
bool slot2On, bool slot2On,
bool tdmaStereo, bool tdmaStereo,
bool pllLock) bool pllLock,
bool udpCopyAudio,
const QString& udpAddress,
quint16 udpPort,
bool force)
{ {
return new MsgConfigureDSDDemod(rfBandwidth, return new MsgConfigureDSDDemod(rfBandwidth,
demodGain, demodGain,
@ -155,7 +167,11 @@ private:
slot1On, slot1On,
slot2On, slot2On,
tdmaStereo, tdmaStereo,
pllLock); pllLock,
udpCopyAudio,
udpAddress,
udpPort,
force);
} }
private: private:
@ -173,6 +189,10 @@ private:
bool m_slot2On; bool m_slot2On;
bool m_tdmaStereo; bool m_tdmaStereo;
bool m_pllLock; bool m_pllLock;
bool m_udpCopyAudio;
QString m_udpAddress;
quint16 m_udpPort;
bool m_force;
MsgConfigureDSDDemod(int rfBandwidth, MsgConfigureDSDDemod(int rfBandwidth,
int demodGain, int demodGain,
@ -187,7 +207,11 @@ private:
bool slot1On, bool slot1On,
bool slot2On, bool slot2On,
bool tdmaStereo, bool tdmaStereo,
bool pllLock) : bool pllLock,
bool udpCopyAudio,
const QString& udpAddress,
quint16 udpPort,
bool force) :
Message(), Message(),
m_rfBandwidth(rfBandwidth), m_rfBandwidth(rfBandwidth),
m_demodGain(demodGain), m_demodGain(demodGain),
@ -202,7 +226,11 @@ private:
m_slot1On(slot1On), m_slot1On(slot1On),
m_slot2On(slot2On), m_slot2On(slot2On),
m_tdmaStereo(tdmaStereo), m_tdmaStereo(tdmaStereo),
m_pllLock(pllLock) m_pllLock(pllLock),
m_udpCopyAudio(udpCopyAudio),
m_udpAddress(udpAddress),
m_udpPort(udpPort),
m_force(force)
{ } { }
}; };
@ -235,6 +263,9 @@ private:
bool m_slot2On; bool m_slot2On;
bool m_tdmaStereo; bool m_tdmaStereo;
bool m_pllLock; bool m_pllLock;
bool m_udpCopyAudio;
QString m_udpAddress;
quint16 m_udpPort;
Config() : Config() :
m_inputSampleRate(-1), m_inputSampleRate(-1),
@ -253,7 +284,10 @@ private:
m_slot1On(false), m_slot1On(false),
m_slot2On(false), m_slot2On(false),
m_tdmaStereo(false), m_tdmaStereo(false),
m_pllLock(true) m_pllLock(true),
m_udpCopyAudio(false),
m_udpAddress("127.0.0.1"),
m_udpPort(9999)
{ } { }
}; };
@ -296,8 +330,11 @@ private:
QMutex m_settingsMutex; QMutex m_settingsMutex;
PhaseDiscriminators m_phaseDiscri; PhaseDiscriminators m_phaseDiscri;
UDPSink<FixReal> *m_udpBufferMono;
void apply(); static const int m_udpBlockSize;
void apply(bool force = false);
}; };
#endif // INCLUDE_DSDDEMOD_H #endif // INCLUDE_DSDDEMOD_H

View File

@ -180,7 +180,7 @@ bool DSDDemodGUI::deserialize(const QByteArray& data)
m_channelMarker.blockSignals(false); m_channelMarker.blockSignals(false);
updateMyPosition(); // we do it also here to be able to refresh with latest settings updateMyPosition(); // we do it also here to be able to refresh with latest settings
applySettings(); applySettings(true);
return true; return true;
} }
else else
@ -360,7 +360,7 @@ DSDDemodGUI::DSDDemodGUI(PluginAPI* pluginAPI, DeviceSourceAPI *deviceAPI, QWidg
ui->scopeGUI->setBuddies(m_scopeVis->getInputMessageQueue(), m_scopeVis, ui->glScope); ui->scopeGUI->setBuddies(m_scopeVis->getInputMessageQueue(), m_scopeVis, ui->glScope);
updateMyPosition(); updateMyPosition();
applySettings(); applySettings(true);
} }
DSDDemodGUI::~DSDDemodGUI() DSDDemodGUI::~DSDDemodGUI()
@ -387,7 +387,7 @@ void DSDDemodGUI::updateMyPosition()
} }
} }
void DSDDemodGUI::applySettings() void DSDDemodGUI::applySettings(bool force)
{ {
if (m_doApplySettings) if (m_doApplySettings)
{ {
@ -425,7 +425,11 @@ void DSDDemodGUI::applySettings()
m_slot1On, m_slot1On,
m_slot2On, m_slot2On,
m_tdmaStereo, m_tdmaStereo,
ui->symbolPLLLock->isChecked()); ui->symbolPLLLock->isChecked(),
ui->udpOutput->isChecked(),
m_channelMarker.getUDPAddress(),
m_channelMarker.getUDPSendPort(),
force);
} }
} }

View File

@ -119,7 +119,7 @@ private:
virtual ~DSDDemodGUI(); virtual ~DSDDemodGUI();
void blockApplySettings(bool block); void blockApplySettings(bool block);
void applySettings(); void applySettings(bool force = false);
void updateMyPosition(); void updateMyPosition();
void leaveEvent(QEvent*); void leaveEvent(QEvent*);

View File

@ -843,6 +843,16 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="ButtonSwitch" name="udpOutput">
<property name="toolTip">
<string>Copy audio output to UDP</string>
</property>
<property name="text">
<string>U</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>