1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-05-23 18:52:28 -04:00

Multiple audio support: WFM demodulator

This commit is contained in:
f4exb 2018-03-28 07:44:54 +02:00
parent ae0470218c
commit 44b4b3cc85
11 changed files with 84 additions and 11 deletions

View File

@ -453,6 +453,7 @@ void BFMDemod::applySettings(const BFMDemodSettings& settings, bool force)
<< " m_rdsActive: " << settings.m_rdsActive
<< " m_udpAddress: " << settings.m_udpAddress
<< " m_udpPort: " << settings.m_udpPort
<< " m_audioDeviceName: " << settings.m_audioDeviceName
<< " force: " << force;
if ((settings.m_audioStereo && (settings.m_audioStereo != m_settings.m_audioStereo)) || force)

View File

@ -224,9 +224,9 @@ private:
static const int m_udpBlockSize;
void applyAudioSampleRate(int sampleRate);
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force = false);
void applySettings(const BFMDemodSettings& settings, bool force = false);
void applyAudioSampleRate(int sampleRate);
};
#endif // INCLUDE_BFMDEMOD_H

View File

@ -1,5 +1,7 @@
project(wfm)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(wfm_SOURCES
wfmdemod.cpp
wfmdemodgui.cpp

View File

@ -60,6 +60,7 @@ WFMDemod::WFMDemod(DeviceSourceAPI* deviceAPI) :
m_audioBufferFill = 0;
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo, getInputMessageQueue());
m_audioSampleRate = DSPEngine::instance()->getAudioDeviceManager()->getOutputSampleRate();
m_audioNetSink = new AudioNetSink(0); // parent thread allocated dynamically - no RTP
m_audioNetSink->setDestination(m_settings.m_udpAddress, m_settings.m_udpPort);
@ -243,6 +244,20 @@ bool WFMDemod::handleMessage(const Message& cmd)
m_audioNetSink->moveToThread(const_cast<QThread*>(thread)); // use the thread for udp sinks
return true;
}
else if (DSPConfigureAudio::match(cmd))
{
DSPConfigureAudio& cfg = (DSPConfigureAudio&) cmd;
uint32_t sampleRate = cfg.getSampleRate();
qDebug() << "WFMDemod::handleMessage: DSPConfigureAudio:"
<< " sampleRate: " << sampleRate;
if (sampleRate != m_audioSampleRate) {
applyAudioSampleRate(sampleRate);
}
return true;
}
else if (DSPSignalNotification::match(cmd))
{
return true;
@ -253,6 +268,21 @@ bool WFMDemod::handleMessage(const Message& cmd)
}
}
void WFMDemod::applyAudioSampleRate(int sampleRate)
{
qDebug("WFMDemod::applyAudioSampleRate: %d", sampleRate);
m_settingsMutex.lock();
m_interpolator.create(16, m_inputSampleRate, m_settings.m_afBandwidth);
m_interpolatorDistanceRemain = (Real) m_inputSampleRate / sampleRate;
m_interpolatorDistance = (Real) m_inputSampleRate / (Real) sampleRate;
m_settingsMutex.unlock();
m_audioSampleRate = sampleRate;
}
void WFMDemod::applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force)
{
qDebug() << "WFMDemod::applyChannelSettings:"
@ -269,8 +299,8 @@ void WFMDemod::applyChannelSettings(int inputSampleRate, int inputFrequencyOffse
{
qDebug() << "WFMDemod::applyChannelSettings: m_interpolator.create";
m_interpolator.create(16, inputSampleRate, m_settings.m_afBandwidth);
m_interpolatorDistanceRemain = (Real) inputSampleRate / (Real) m_settings.m_audioSampleRate;
m_interpolatorDistance = (Real) inputSampleRate / (Real) m_settings.m_audioSampleRate;
m_interpolatorDistanceRemain = (Real) inputSampleRate / (Real) m_audioSampleRate;
m_interpolatorDistance = (Real) inputSampleRate / (Real) m_audioSampleRate;
qDebug() << "WFMDemod::applySettings: m_rfFilter->create_filter";
Real lowCut = -(m_settings.m_rfBandwidth / 2.0) / inputSampleRate;
Real hiCut = (m_settings.m_rfBandwidth / 2.0) / inputSampleRate;
@ -295,17 +325,17 @@ void WFMDemod::applySettings(const WFMDemodSettings& settings, bool force)
<< " m_copyAudioToUDP: " << settings.m_copyAudioToUDP
<< " m_udpAddress: " << settings.m_udpAddress
<< " m_udpPort: " << settings.m_udpPort
<< " m_audioDeviceName: " << settings.m_audioDeviceName
<< " force: " << force;
if((settings.m_audioSampleRate != m_settings.m_audioSampleRate) ||
(settings.m_afBandwidth != m_settings.m_afBandwidth) ||
if((settings.m_afBandwidth != m_settings.m_afBandwidth) ||
(settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force)
{
m_settingsMutex.lock();
qDebug() << "WFMDemod::applySettings: m_interpolator.create";
m_interpolator.create(16, m_inputSampleRate, settings.m_afBandwidth);
m_interpolatorDistanceRemain = (Real) m_inputSampleRate / (Real) settings.m_audioSampleRate;
m_interpolatorDistance = (Real) m_inputSampleRate / (Real) settings.m_audioSampleRate;
m_interpolatorDistanceRemain = (Real) m_inputSampleRate / (Real) m_audioSampleRate;
m_interpolatorDistance = (Real) m_inputSampleRate / (Real) m_audioSampleRate;
qDebug() << "WFMDemod::applySettings: m_rfFilter->create_filter";
Real lowCut = -(settings.m_rfBandwidth / 2.0) / m_inputSampleRate;
Real hiCut = (settings.m_rfBandwidth / 2.0) / m_inputSampleRate;
@ -329,6 +359,19 @@ void WFMDemod::applySettings(const WFMDemodSettings& settings, bool force)
m_audioNetSink->setDestination(settings.m_udpAddress, settings.m_udpPort);
}
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
{
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
int audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_audioDeviceName);
//qDebug("AMDemod::applySettings: audioDeviceName: %s audioDeviceIndex: %d", qPrintable(settings.m_audioDeviceName), audioDeviceIndex);
audioDeviceManager->addAudioSink(&m_audioFifo, getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex);
if (m_audioSampleRate != audioSampleRate) {
applyAudioSampleRate(audioSampleRate);
}
}
m_settings = settings;
}

View File

@ -135,6 +135,7 @@ private:
int m_inputSampleRate;
int m_inputFrequencyOffset;
WFMDemodSettings m_settings;
quint32 m_audioSampleRate;
NCO m_nco;
Interpolator m_interpolator; //!< Interpolator between sample rate sent from DSP engine and requested RF bandwidth (rational)
@ -165,6 +166,7 @@ private:
static const int m_udpBlockSize;
void applyAudioSampleRate(int sampleRate);
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force = false);
void applySettings(const WFMDemodSettings& settings, bool force = false);
};

View File

@ -13,6 +13,8 @@
#include "util/simpleserializer.h"
#include "util/db.h"
#include "gui/basicchannelsettingsdialog.h"
#include "gui/crightclickenabler.h"
#include "gui/audioselectdialog.h"
#include "mainwindow.h"
#include "wfmdemod.h"
@ -177,6 +179,9 @@ WFMDemodGUI::WFMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban
connect(&MainWindow::getInstance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick()));
CRightClickEnabler *audioMuteRightClickEnabler = new CRightClickEnabler(ui->audioMute);
connect(audioMuteRightClickEnabler, SIGNAL(rightClick()), this, SLOT(audioSelect()));
ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
@ -287,6 +292,19 @@ void WFMDemodGUI::enterEvent(QEvent*)
m_channelMarker.setHighlighted(true);
}
void WFMDemodGUI::audioSelect()
{
qDebug("WFMDemodGUI::audioSelect");
AudioSelectDialog audioSelect(DSPEngine::instance()->getAudioDeviceManager(), m_settings.m_audioDeviceName);
audioSelect.exec();
if (audioSelect.m_selected)
{
m_settings.m_audioDeviceName = audioSelect.m_audioDeviceName;
applySettings();
}
}
void WFMDemodGUI::tick()
{
double magsqAvg, magsqPeak;

View File

@ -83,6 +83,7 @@ private slots:
void on_copyAudioToUDP_toggled(bool copy);
void onWidgetRolled(QWidget* widget, bool rollDown);
void onMenuDialogCalled(const QPoint& p);
void audioSelect();
void tick();
};

View File

@ -377,6 +377,9 @@
</item>
<item>
<widget class="QToolButton" name="audioMute">
<property name="toolTip">
<string>Left: audio mute Right: select audio device</string>
</property>
<property name="text">
<string/>
</property>

View File

@ -42,12 +42,12 @@ void WFMDemodSettings::resetToDefaults()
m_volume = 2.0;
m_squelch = -60.0;
m_audioMute = false;
m_audioSampleRate = DSPEngine::instance()->getDefaultAudioSampleRate();
m_copyAudioToUDP = false;
m_udpAddress = "127.0.0.1";
m_udpPort = 9999;
m_rgbColor = QColor(0, 0, 255).rgb();
m_title = "WFM Demodulator";
m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName;
}
QByteArray WFMDemodSettings::serialize() const
@ -60,11 +60,13 @@ QByteArray WFMDemodSettings::serialize() const
s.writeS32(5, m_squelch);
s.writeU32(7, m_rgbColor);
s.writeString(8, m_title);
s.writeString(9, m_audioDeviceName);
if (m_channelMarker) {
s.writeBlob(11, m_channelMarker->serialize());
}
return s.final();
}
@ -96,6 +98,7 @@ bool WFMDemodSettings::deserialize(const QByteArray& data)
m_squelch = tmp;
d.readU32(7, &m_rgbColor);
d.readString(8, &m_title, "WFM Demodulator");
d.readString(9, &m_audioDeviceName, AudioDeviceManager::m_defaultDeviceName);
d.readBlob(11, &bytetmp);

View File

@ -30,12 +30,12 @@ struct WFMDemodSettings
Real m_volume;
Real m_squelch;
bool m_audioMute;
quint32 m_audioSampleRate;
bool m_copyAudioToUDP;
QString m_udpAddress;
quint16 m_udpPort;
quint32 m_rgbColor;
QString m_title;
QString m_audioDeviceName;
Serializable *m_channelMarker;

View File

@ -8,7 +8,7 @@
const PluginDescriptor WFMPlugin::m_pluginDescriptor = {
QString("WFM Demodulator"),
QString("3.12.0"),
QString("3.14.0"),
QString("(c) Edouard Griffiths, F4EXB"),
QString("https://github.com/f4exb/sdrangel"),
true,