Multiple audio support: BFM demodulator

This commit is contained in:
f4exb 2018-03-27 23:57:29 +02:00
parent 61aad30cbb
commit ae0470218c
9 changed files with 90 additions and 22 deletions

View File

@ -1,5 +1,7 @@
project(bfm)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(bfm_SOURCES
bfmdemod.cpp
bfmdemodgui.cpp

View File

@ -54,6 +54,9 @@ BFMDemod::BFMDemod(DeviceSourceAPI *deviceAPI) :
{
setObjectName(m_channelId);
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo, getInputMessageQueue());
m_audioSampleRate = DSPEngine::instance()->getAudioDeviceManager()->getOutputSampleRate();
m_magsq = 0.0f;
m_magsqSum = 0.0f;
m_magsqPeak = 0.0f;
@ -77,15 +80,13 @@ BFMDemod::BFMDemod(DeviceSourceAPI *deviceAPI) :
m_rfFilter = new fftfilt(-50000.0 / 384000.0, 50000.0 / 384000.0, filtFftLen);
m_deemphasisFilterX.configure(default_deemphasis * m_settings.m_audioSampleRate * 1.0e-6);
m_deemphasisFilterY.configure(default_deemphasis * m_settings.m_audioSampleRate * 1.0e-6);
m_deemphasisFilterX.configure(default_deemphasis * m_audioSampleRate * 1.0e-6);
m_deemphasisFilterY.configure(default_deemphasis * m_audioSampleRate * 1.0e-6);
m_phaseDiscri.setFMScaling(384000/m_fmExcursion);
m_audioBuffer.resize(16384);
m_audioBufferFill = 0;
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo, getInputMessageQueue());
applyChannelSettings(m_inputSampleRate, m_inputFrequencyOffset, true);
applySettings(m_settings, true);
@ -338,6 +339,20 @@ bool BFMDemod::handleMessage(const Message& cmd)
return true;
}
else if (DSPConfigureAudio::match(cmd))
{
DSPConfigureAudio& cfg = (DSPConfigureAudio&) cmd;
uint32_t sampleRate = cfg.getSampleRate();
qDebug() << "BFMDemod::handleMessage: DSPConfigureAudio:"
<< " sampleRate: " << sampleRate;
if (sampleRate != m_audioSampleRate) {
applyAudioSampleRate(sampleRate);
}
return true;
}
else if (BasebandSampleSink::MsgThreadedSink::match(cmd))
{
return true;
@ -361,6 +376,28 @@ bool BFMDemod::handleMessage(const Message& cmd)
}
}
void BFMDemod::applyAudioSampleRate(int sampleRate)
{
qDebug("BFMDemod::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_interpolatorStereo.create(16, m_inputSampleRate, m_settings.m_afBandwidth);
m_interpolatorStereoDistanceRemain = (Real) m_inputSampleRate / sampleRate;
m_interpolatorStereoDistance = (Real) m_inputSampleRate / (Real) sampleRate;
m_deemphasisFilterX.configure(default_deemphasis * sampleRate * 1.0e-6);
m_deemphasisFilterY.configure(default_deemphasis * sampleRate * 1.0e-6);
m_settingsMutex.unlock();
m_audioSampleRate = sampleRate;
}
void BFMDemod::applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force)
{
qDebug() << "BFMDemod::applyChannelSettings:"
@ -380,12 +417,12 @@ void BFMDemod::applyChannelSettings(int inputSampleRate, int inputFrequencyOffse
m_settingsMutex.lock();
m_interpolator.create(16, inputSampleRate, m_settings.m_afBandwidth);
m_interpolatorDistanceRemain = (Real) inputSampleRate / m_settings.m_audioSampleRate;
m_interpolatorDistance = (Real) inputSampleRate / (Real) m_settings.m_audioSampleRate;
m_interpolatorDistanceRemain = (Real) inputSampleRate / m_audioSampleRate;
m_interpolatorDistance = (Real) inputSampleRate / (Real) m_audioSampleRate;
m_interpolatorStereo.create(16, inputSampleRate, m_settings.m_afBandwidth);
m_interpolatorStereoDistanceRemain = (Real) inputSampleRate / m_settings.m_audioSampleRate;
m_interpolatorStereoDistance = (Real) inputSampleRate / (Real) m_settings.m_audioSampleRate;
m_interpolatorStereoDistanceRemain = (Real) inputSampleRate / m_audioSampleRate;
m_interpolatorStereoDistance = (Real) inputSampleRate / (Real) m_audioSampleRate;
m_interpolatorRDS.create(4, inputSampleRate, 600.0);
m_interpolatorRDSDistanceRemain = (Real) inputSampleRate / 250000.0;
@ -428,12 +465,12 @@ void BFMDemod::applySettings(const BFMDemodSettings& settings, bool force)
m_settingsMutex.lock();
m_interpolator.create(16, m_inputSampleRate, settings.m_afBandwidth);
m_interpolatorDistanceRemain = (Real) m_inputSampleRate / settings.m_audioSampleRate;
m_interpolatorDistance = (Real) m_inputSampleRate / (Real) settings.m_audioSampleRate;
m_interpolatorDistanceRemain = (Real) m_inputSampleRate / m_audioSampleRate;
m_interpolatorDistance = (Real) m_inputSampleRate / (Real) m_audioSampleRate;
m_interpolatorStereo.create(16, m_inputSampleRate, settings.m_afBandwidth);
m_interpolatorStereoDistanceRemain = (Real) m_inputSampleRate / settings.m_audioSampleRate;
m_interpolatorStereoDistance = (Real) m_inputSampleRate / (Real) settings.m_audioSampleRate;
m_interpolatorStereoDistanceRemain = (Real) m_inputSampleRate / m_audioSampleRate;
m_interpolatorStereoDistance = (Real) m_inputSampleRate / (Real) m_audioSampleRate;
m_interpolatorRDS.create(4, m_inputSampleRate, 600.0);
m_interpolatorRDSDistanceRemain = (Real) m_inputSampleRate / 250000.0;
@ -453,12 +490,11 @@ void BFMDemod::applySettings(const BFMDemodSettings& settings, bool force)
m_settingsMutex.unlock();
}
if ((settings.m_afBandwidth != m_settings.m_afBandwidth) ||
(settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force)
if ((settings.m_afBandwidth != m_settings.m_afBandwidth) || force)
{
m_settingsMutex.lock();
qDebug() << "BFMDemod::handleMessage: m_lowpass.create";
m_lowpass.create(21, settings.m_audioSampleRate, settings.m_afBandwidth);
m_lowpass.create(21, m_audioSampleRate, settings.m_afBandwidth);
m_settingsMutex.unlock();
}
@ -469,10 +505,17 @@ void BFMDemod::applySettings(const BFMDemodSettings& settings, bool force)
m_squelchLevel *= m_squelchLevel;
}
if ((settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force)
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
{
m_deemphasisFilterX.configure(default_deemphasis * settings.m_audioSampleRate * 1.0e-6);
m_deemphasisFilterY.configure(default_deemphasis * settings.m_audioSampleRate * 1.0e-6);
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

@ -169,6 +169,7 @@ private:
int m_inputSampleRate;
int m_inputFrequencyOffset;
BFMDemodSettings m_settings;
quint32 m_audioSampleRate;
NCO m_nco;
Interpolator m_interpolator; //!< Interpolator between fixed demod bandwidth and audio bandwidth (rational)
@ -225,6 +226,7 @@ private:
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

@ -36,6 +36,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 "bfmdemodsettings.h"
@ -331,6 +333,9 @@ BFMDemodGUI::BFMDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban
ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
ui->channelPowerMeter->setColorTheme(LevelMeterSignalDB::ColorGreenAndBlue);
CRightClickEnabler *audioMuteRightClickEnabler = new CRightClickEnabler(ui->audioStereo);
connect(audioMuteRightClickEnabler, SIGNAL(rightClick()), this, SLOT(audioSelect()));
setAttribute(Qt::WA_DeleteOnClose, true);
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
@ -455,6 +460,19 @@ void BFMDemodGUI::enterEvent(QEvent*)
m_channelMarker.setHighlighted(true);
}
void BFMDemodGUI::audioSelect()
{
qDebug("BFMDemodGUI::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 BFMDemodGUI::tick()
{
double magsqAvg, magsqPeak;

View File

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

View File

@ -163,7 +163,7 @@
<item>
<widget class="QToolButton" name="audioStereo">
<property name="toolTip">
<string>Mono/Stereo toggle and pilot lock indicator</string>
<string>Light: Pilot lock indicator Left: Mono/Stereo toggle Right: select audio device</string>
</property>
<property name="autoFillBackground">
<bool>true</bool>

View File

@ -41,7 +41,6 @@ void BFMDemodSettings::resetToDefaults()
m_afBandwidth = 15000;
m_volume = 2.0;
m_squelch = -60.0;
m_audioSampleRate = DSPEngine::instance()->getDefaultAudioSampleRate();
m_audioStereo = false;
m_lsbStereo = false;
m_showPilot = false;
@ -50,6 +49,7 @@ void BFMDemodSettings::resetToDefaults()
m_udpPort = 9999;
m_rgbColor = QColor(80, 120, 228).rgb();
m_title = "Broadcast FM Demod";
m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName;
}
QByteArray BFMDemodSettings::serialize() const
@ -74,6 +74,7 @@ QByteArray BFMDemodSettings::serialize() const
}
s.writeString(12, m_title);
s.writeString(13, m_audioDeviceName);
return s.final();
}
@ -122,6 +123,7 @@ bool BFMDemodSettings::deserialize(const QByteArray& data)
}
d.readString(12, &m_title, "Broadcast FM Demod");
d.readString(13, &m_audioDeviceName, AudioDeviceManager::m_defaultDeviceName);
return true;
}

View File

@ -28,7 +28,6 @@ struct BFMDemodSettings
Real m_afBandwidth;
Real m_volume;
Real m_squelch;
quint32 m_audioSampleRate;
bool m_audioStereo;
bool m_lsbStereo;
bool m_showPilot;
@ -37,6 +36,7 @@ struct BFMDemodSettings
quint16 m_udpPort;
quint32 m_rgbColor;
QString m_title;
QString m_audioDeviceName;
Serializable *m_channelMarker;
Serializable *m_spectrumGUI;

View File

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