mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-26 09:48:45 -05:00
Multiple audio support: BFM demodulator
This commit is contained in:
parent
61aad30cbb
commit
ae0470218c
@ -1,5 +1,7 @@
|
||||
project(bfm)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
|
||||
set(bfm_SOURCES
|
||||
bfmdemod.cpp
|
||||
bfmdemodgui.cpp
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -115,6 +115,7 @@ private slots:
|
||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||
void onMenuDialogCalled(const QPoint& p);
|
||||
void handleInputMessages();
|
||||
void audioSelect();
|
||||
void tick();
|
||||
};
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user