mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-05-29 05:22:25 -04:00
NFM demod: implemented option to copy audio to UDP
This commit is contained in:
parent
939e423c02
commit
af63a8ed5c
@ -28,10 +28,11 @@
|
|||||||
#include "dsp/dspengine.h"
|
#include "dsp/dspengine.h"
|
||||||
#include "nfmdemodgui.h"
|
#include "nfmdemodgui.h"
|
||||||
|
|
||||||
static const double afSqTones[2] = {1000.0, 6000.0}; // {1200.0, 8000.0};
|
|
||||||
|
|
||||||
MESSAGE_CLASS_DEFINITION(NFMDemod::MsgConfigureNFMDemod, Message)
|
MESSAGE_CLASS_DEFINITION(NFMDemod::MsgConfigureNFMDemod, Message)
|
||||||
|
|
||||||
|
static const double afSqTones[2] = {1000.0, 6000.0}; // {1200.0, 8000.0};
|
||||||
|
const int NFMDemod::m_udpBlockSize = 512;
|
||||||
|
|
||||||
NFMDemod::NFMDemod() :
|
NFMDemod::NFMDemod() :
|
||||||
m_ctcssIndex(0),
|
m_ctcssIndex(0),
|
||||||
m_sampleCount(0),
|
m_sampleCount(0),
|
||||||
@ -77,11 +78,13 @@ NFMDemod::NFMDemod() :
|
|||||||
m_afSquelch.setCoefficients(24, 600, 48000.0, 200, 0); // 0.5ms test period, 300ms average span, 48kS/s SR, 100ms attack, no decay
|
m_afSquelch.setCoefficients(24, 600, 48000.0, 200, 0); // 0.5ms test period, 300ms average span, 48kS/s SR, 100ms attack, no decay
|
||||||
|
|
||||||
DSPEngine::instance()->addAudioSink(&m_audioFifo);
|
DSPEngine::instance()->addAudioSink(&m_audioFifo);
|
||||||
|
m_udpBufferAudio = new UDPSink<qint16>(this, m_udpBlockSize, m_config.m_udpPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
NFMDemod::~NFMDemod()
|
NFMDemod::~NFMDemod()
|
||||||
{
|
{
|
||||||
DSPEngine::instance()->removeAudioSink(&m_audioFifo);
|
DSPEngine::instance()->removeAudioSink(&m_audioFifo);
|
||||||
|
delete m_udpBufferAudio;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NFMDemod::configure(MessageQueue* messageQueue,
|
void NFMDemod::configure(MessageQueue* messageQueue,
|
||||||
@ -94,6 +97,9 @@ void NFMDemod::configure(MessageQueue* messageQueue,
|
|||||||
Real squelch,
|
Real squelch,
|
||||||
bool ctcssOn,
|
bool ctcssOn,
|
||||||
bool audioMute,
|
bool audioMute,
|
||||||
|
bool copyAudioToUDP,
|
||||||
|
const QString& udpAddress,
|
||||||
|
qint16 udpPort,
|
||||||
bool force)
|
bool force)
|
||||||
{
|
{
|
||||||
Message* cmd = MsgConfigureNFMDemod::create(rfBandwidth,
|
Message* cmd = MsgConfigureNFMDemod::create(rfBandwidth,
|
||||||
@ -105,6 +111,9 @@ void NFMDemod::configure(MessageQueue* messageQueue,
|
|||||||
squelch,
|
squelch,
|
||||||
ctcssOn,
|
ctcssOn,
|
||||||
audioMute,
|
audioMute,
|
||||||
|
copyAudioToUDP,
|
||||||
|
udpAddress,
|
||||||
|
udpPort,
|
||||||
force);
|
force);
|
||||||
messageQueue->push(cmd);
|
messageQueue->push(cmd);
|
||||||
}
|
}
|
||||||
@ -282,12 +291,14 @@ void NFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
|
|||||||
if (m_running.m_ctcssOn && m_ctcssIndexSelected && (m_ctcssIndexSelected != m_ctcssIndex))
|
if (m_running.m_ctcssOn && m_ctcssIndexSelected && (m_ctcssIndexSelected != m_ctcssIndex))
|
||||||
{
|
{
|
||||||
sample = 0;
|
sample = 0;
|
||||||
|
if (m_running.m_copyAudioToUDP) m_udpBufferAudio->write(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
demod = m_bandpass.filter(demod);
|
demod = m_bandpass.filter(demod);
|
||||||
Real squelchFactor = StepFunctions::smootherstep((Real) (m_squelchCount - m_squelchGate) / 480.0f);
|
Real squelchFactor = StepFunctions::smootherstep((Real) (m_squelchCount - m_squelchGate) / 480.0f);
|
||||||
sample = demod * m_running.m_volume * squelchFactor;
|
sample = demod * m_running.m_volume * squelchFactor;
|
||||||
|
if (m_running.m_copyAudioToUDP) m_udpBufferAudio->write(demod * 5.0f * squelchFactor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -299,6 +310,7 @@ void NFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
|
|||||||
}
|
}
|
||||||
|
|
||||||
sample = 0;
|
sample = 0;
|
||||||
|
if (m_running.m_copyAudioToUDP) m_udpBufferAudio->write(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_audioBuffer[m_audioBufferFill].l = sample;
|
m_audioBuffer[m_audioBufferFill].l = sample;
|
||||||
@ -380,6 +392,9 @@ bool NFMDemod::handleMessage(const Message& cmd)
|
|||||||
m_config.m_squelch = cfg.getSquelch();
|
m_config.m_squelch = cfg.getSquelch();
|
||||||
m_config.m_ctcssOn = cfg.getCtcssOn();
|
m_config.m_ctcssOn = cfg.getCtcssOn();
|
||||||
m_config.m_audioMute = cfg.getAudioMute();
|
m_config.m_audioMute = cfg.getAudioMute();
|
||||||
|
m_config.m_copyAudioToUDP = cfg.getCopyAudioToUDP();
|
||||||
|
m_config.m_udpAddress = cfg.getUDPAddress();
|
||||||
|
m_config.m_udpPort = cfg.getUDPPort();
|
||||||
|
|
||||||
apply(cfg.getForce());
|
apply(cfg.getForce());
|
||||||
|
|
||||||
@ -392,6 +407,9 @@ bool NFMDemod::handleMessage(const Message& cmd)
|
|||||||
<< " m_squelch: " << m_squelchLevel
|
<< " m_squelch: " << m_squelchLevel
|
||||||
<< " m_ctcssOn: " << m_config.m_ctcssOn
|
<< " m_ctcssOn: " << m_config.m_ctcssOn
|
||||||
<< " m_audioMute: " << m_config.m_audioMute
|
<< " m_audioMute: " << m_config.m_audioMute
|
||||||
|
<< " m_copyAudioToUDP: " << m_config.m_copyAudioToUDP
|
||||||
|
<< " m_udpAddress: " << m_config.m_udpAddress
|
||||||
|
<< " m_udpPort: " << m_config.m_udpPort
|
||||||
<< " force: " << cfg.getForce();
|
<< " force: " << cfg.getForce();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -458,16 +476,12 @@ void NFMDemod::apply(bool force)
|
|||||||
//m_afSquelch.setThreshold(m_squelchLevel);
|
//m_afSquelch.setThreshold(m_squelchLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_running.m_inputSampleRate = m_config.m_inputSampleRate;
|
if ((m_config.m_udpAddress != m_running.m_udpAddress)
|
||||||
m_running.m_inputFrequencyOffset = m_config.m_inputFrequencyOffset;
|
|| (m_config.m_udpPort != m_running.m_udpPort) || force)
|
||||||
m_running.m_rfBandwidth = m_config.m_rfBandwidth;
|
{
|
||||||
m_running.m_afBandwidth = m_config.m_afBandwidth;
|
m_udpBufferAudio->setAddress(m_config.m_udpAddress);
|
||||||
m_running.m_fmDeviation = m_config.m_fmDeviation;
|
m_udpBufferAudio->setPort(m_config.m_udpPort);
|
||||||
m_running.m_squelchGate = m_config.m_squelchGate;
|
}
|
||||||
m_running.m_deltaSquelch = m_config.m_deltaSquelch;
|
|
||||||
m_running.m_squelch = m_config.m_squelch;
|
m_running = m_config;
|
||||||
m_running.m_volume = m_config.m_volume;
|
|
||||||
m_running.m_audioSampleRate = m_config.m_audioSampleRate;
|
|
||||||
m_running.m_ctcssOn = m_config.m_ctcssOn;
|
|
||||||
m_running.m_audioMute = m_config.m_audioMute;
|
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,9 @@ public:
|
|||||||
Real squelch,
|
Real squelch,
|
||||||
bool ctcssOn,
|
bool ctcssOn,
|
||||||
bool audioMute,
|
bool audioMute,
|
||||||
|
bool copyAudioToUDP,
|
||||||
|
const QString& udpAddress,
|
||||||
|
qint16 udpPort,
|
||||||
bool force);
|
bool force);
|
||||||
|
|
||||||
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool po);
|
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool po);
|
||||||
@ -98,6 +101,9 @@ private:
|
|||||||
Real getSquelch() const { return m_squelch; }
|
Real getSquelch() const { return m_squelch; }
|
||||||
bool getCtcssOn() const { return m_ctcssOn; }
|
bool getCtcssOn() const { return m_ctcssOn; }
|
||||||
bool getAudioMute() const { return m_audioMute; }
|
bool getAudioMute() const { return m_audioMute; }
|
||||||
|
bool getCopyAudioToUDP() const { return m_copyAudioToUDP; }
|
||||||
|
const QString& getUDPAddress() const { return m_udpAddress; }
|
||||||
|
quint16 getUDPPort() const { return m_udpPort; }
|
||||||
bool getForce() const { return m_force; }
|
bool getForce() const { return m_force; }
|
||||||
|
|
||||||
static MsgConfigureNFMDemod* create(Real rfBandwidth,
|
static MsgConfigureNFMDemod* create(Real rfBandwidth,
|
||||||
@ -109,6 +115,9 @@ private:
|
|||||||
Real squelch,
|
Real squelch,
|
||||||
bool ctcssOn,
|
bool ctcssOn,
|
||||||
bool audioMute,
|
bool audioMute,
|
||||||
|
bool copyAudioToUDP,
|
||||||
|
const QString& udpAddress,
|
||||||
|
qint16 udpPort,
|
||||||
bool force)
|
bool force)
|
||||||
{
|
{
|
||||||
return new MsgConfigureNFMDemod(
|
return new MsgConfigureNFMDemod(
|
||||||
@ -121,6 +130,9 @@ private:
|
|||||||
squelch,
|
squelch,
|
||||||
ctcssOn,
|
ctcssOn,
|
||||||
audioMute,
|
audioMute,
|
||||||
|
copyAudioToUDP,
|
||||||
|
udpAddress,
|
||||||
|
udpPort,
|
||||||
force);
|
force);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,6 +146,9 @@ private:
|
|||||||
Real m_squelch;
|
Real m_squelch;
|
||||||
bool m_ctcssOn;
|
bool m_ctcssOn;
|
||||||
bool m_audioMute;
|
bool m_audioMute;
|
||||||
|
bool m_copyAudioToUDP;
|
||||||
|
QString m_udpAddress;
|
||||||
|
quint16 m_udpPort;
|
||||||
bool m_force;
|
bool m_force;
|
||||||
|
|
||||||
MsgConfigureNFMDemod(Real rfBandwidth,
|
MsgConfigureNFMDemod(Real rfBandwidth,
|
||||||
@ -145,6 +160,9 @@ private:
|
|||||||
Real squelch,
|
Real squelch,
|
||||||
bool ctcssOn,
|
bool ctcssOn,
|
||||||
bool audioMute,
|
bool audioMute,
|
||||||
|
bool copyAudioToUDP,
|
||||||
|
const QString& udpAddress,
|
||||||
|
qint16 udpPort,
|
||||||
bool force) :
|
bool force) :
|
||||||
Message(),
|
Message(),
|
||||||
m_rfBandwidth(rfBandwidth),
|
m_rfBandwidth(rfBandwidth),
|
||||||
@ -156,6 +174,9 @@ private:
|
|||||||
m_squelch(squelch),
|
m_squelch(squelch),
|
||||||
m_ctcssOn(ctcssOn),
|
m_ctcssOn(ctcssOn),
|
||||||
m_audioMute(audioMute),
|
m_audioMute(audioMute),
|
||||||
|
m_copyAudioToUDP(copyAudioToUDP),
|
||||||
|
m_udpAddress(udpAddress),
|
||||||
|
m_udpPort(udpPort),
|
||||||
m_force(force)
|
m_force(force)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
@ -179,6 +200,9 @@ private:
|
|||||||
bool m_audioMute;
|
bool m_audioMute;
|
||||||
int m_ctcssIndex;
|
int m_ctcssIndex;
|
||||||
quint32 m_audioSampleRate;
|
quint32 m_audioSampleRate;
|
||||||
|
bool m_copyAudioToUDP;
|
||||||
|
QString m_udpAddress;
|
||||||
|
quint16 m_udpPort;
|
||||||
|
|
||||||
Config() :
|
Config() :
|
||||||
m_inputSampleRate(-1),
|
m_inputSampleRate(-1),
|
||||||
@ -193,7 +217,10 @@ private:
|
|||||||
m_ctcssOn(false),
|
m_ctcssOn(false),
|
||||||
m_audioMute(false),
|
m_audioMute(false),
|
||||||
m_ctcssIndex(0),
|
m_ctcssIndex(0),
|
||||||
m_audioSampleRate(0)
|
m_audioSampleRate(0),
|
||||||
|
m_copyAudioToUDP(false),
|
||||||
|
m_udpAddress("127.0.0.1"),
|
||||||
|
m_udpPort(9999)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -237,13 +264,16 @@ private:
|
|||||||
uint m_audioBufferFill;
|
uint m_audioBufferFill;
|
||||||
|
|
||||||
AudioFifo m_audioFifo;
|
AudioFifo m_audioFifo;
|
||||||
|
UDPSink<qint16> *m_udpBufferAudio;
|
||||||
|
|
||||||
NFMDemodGUI *m_nfmDemodGUI;
|
NFMDemodGUI *m_nfmDemodGUI;
|
||||||
QMutex m_settingsMutex;
|
QMutex m_settingsMutex;
|
||||||
|
|
||||||
PhaseDiscriminators m_phaseDiscri;
|
PhaseDiscriminators m_phaseDiscri;
|
||||||
|
|
||||||
void apply(bool force = false);
|
static const int m_udpBlockSize;
|
||||||
|
|
||||||
|
void apply(bool force = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INCLUDE_NFMDEMOD_H
|
#endif // INCLUDE_NFMDEMOD_H
|
||||||
|
@ -247,6 +247,11 @@ void NFMDemodGUI::on_audioMute_toggled(bool checked)
|
|||||||
applySettings();
|
applySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NFMDemodGUI::on_copyAudioToUDP_toggled(bool checked __attribute__((unused)))
|
||||||
|
{
|
||||||
|
applySettings();
|
||||||
|
}
|
||||||
|
|
||||||
void NFMDemodGUI::on_ctcss_currentIndexChanged(int index)
|
void NFMDemodGUI::on_ctcss_currentIndexChanged(int index)
|
||||||
{
|
{
|
||||||
if (m_nfmDemod != 0)
|
if (m_nfmDemod != 0)
|
||||||
@ -378,6 +383,9 @@ void NFMDemodGUI::applySettings(bool force)
|
|||||||
ui->squelch->value(), // -1000 -> 0
|
ui->squelch->value(), // -1000 -> 0
|
||||||
ui->ctcssOn->isChecked(),
|
ui->ctcssOn->isChecked(),
|
||||||
ui->audioMute->isChecked(),
|
ui->audioMute->isChecked(),
|
||||||
|
ui->copyAudioToUDP->isChecked(),
|
||||||
|
m_channelMarker.getUDPAddress(),
|
||||||
|
m_channelMarker.getUDPSendPort(),
|
||||||
force);
|
force);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,7 @@ private slots:
|
|||||||
void on_ctcss_currentIndexChanged(int index);
|
void on_ctcss_currentIndexChanged(int index);
|
||||||
void on_ctcssOn_toggled(bool checked);
|
void on_ctcssOn_toggled(bool checked);
|
||||||
void on_audioMute_toggled(bool checked);
|
void on_audioMute_toggled(bool checked);
|
||||||
|
void on_copyAudioToUDP_toggled(bool checked);
|
||||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||||
void onMenuDialogCalled(const QPoint& p);
|
void onMenuDialogCalled(const QPoint& p);
|
||||||
void tick();
|
void tick();
|
||||||
|
@ -404,6 +404,7 @@ private:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_udpHandler.readSample(t);
|
m_udpHandler.readSample(t);
|
||||||
|
t *= m_running.m_gainIn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -110,7 +110,6 @@ bool UDPSinkGUI::deserialize(const QByteArray& data)
|
|||||||
QByteArray bytetmp;
|
QByteArray bytetmp;
|
||||||
QString strtmp;
|
QString strtmp;
|
||||||
qint32 s32tmp;
|
qint32 s32tmp;
|
||||||
quint32 u32tmp;
|
|
||||||
Real realtmp;
|
Real realtmp;
|
||||||
bool booltmp;
|
bool booltmp;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user