1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-02-03 09:44:01 -05:00

Multiple audio support: DSD demodulator

This commit is contained in:
f4exb 2018-03-28 08:00:27 +02:00
parent 44b4b3cc85
commit c4b092dff0
8 changed files with 71 additions and 5 deletions

View File

@ -1,5 +1,7 @@
project(dsddemod) project(dsddemod)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(dsddemod_SOURCES set(dsddemod_SOURCES
dsddemod.cpp dsddemod.cpp
dsddemodgui.cpp dsddemodgui.cpp

View File

@ -74,6 +74,7 @@ DSDDemod::DSDDemod(DeviceSourceAPI *deviceAPI) :
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo1, getInputMessageQueue()); DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo1, getInputMessageQueue());
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo2, getInputMessageQueue()); DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo2, getInputMessageQueue());
m_audioSampleRate = DSPEngine::instance()->getAudioDeviceManager()->getOutputSampleRate();
applyChannelSettings(m_inputSampleRate, m_inputFrequencyOffset, true); applyChannelSettings(m_inputSampleRate, m_inputFrequencyOffset, true);
applySettings(m_settings, true); applySettings(m_settings, true);
@ -358,6 +359,20 @@ bool DSDDemod::handleMessage(const Message& cmd)
m_dsdDecoder.setMyPoint(cfg.getMyLatitude(), cfg.getMyLongitude()); m_dsdDecoder.setMyPoint(cfg.getMyLatitude(), cfg.getMyLongitude());
return true; return true;
} }
else if (DSPConfigureAudio::match(cmd))
{
DSPConfigureAudio& cfg = (DSPConfigureAudio&) cmd;
uint32_t sampleRate = cfg.getSampleRate();
qDebug() << "DSDDemod::handleMessage: DSPConfigureAudio:"
<< " sampleRate: " << sampleRate;
if (sampleRate != m_audioSampleRate) {
applyAudioSampleRate(sampleRate);
}
return true;
}
else if (BasebandSampleSink::MsgThreadedSink::match(cmd)) else if (BasebandSampleSink::MsgThreadedSink::match(cmd))
{ {
return true; return true;
@ -372,6 +387,17 @@ bool DSDDemod::handleMessage(const Message& cmd)
} }
} }
void DSDDemod::applyAudioSampleRate(int sampleRate)
{
qDebug("DSDDemod::applyAudioSampleRate: %d", sampleRate);
if (sampleRate != 48000) {
qWarning("DSDDemod::applyAudioSampleRate: audio does not work properly with sample rates other than 48 kS/s");
}
m_audioSampleRate = sampleRate;
}
void DSDDemod::applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force) void DSDDemod::applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force)
{ {
qDebug() << "DSDDemod::applyChannelSettings:" qDebug() << "DSDDemod::applyChannelSettings:"
@ -389,7 +415,7 @@ void DSDDemod::applyChannelSettings(int inputSampleRate, int inputFrequencyOffse
m_settingsMutex.lock(); m_settingsMutex.lock();
m_interpolator.create(16, inputSampleRate, (m_settings.m_rfBandwidth) / 2.2); m_interpolator.create(16, inputSampleRate, (m_settings.m_rfBandwidth) / 2.2);
m_interpolatorDistanceRemain = 0; m_interpolatorDistanceRemain = 0;
m_interpolatorDistance = (Real) inputSampleRate / (Real) m_settings.m_audioSampleRate; m_interpolatorDistance = (Real) inputSampleRate / (Real) 48000;
m_settingsMutex.unlock(); m_settingsMutex.unlock();
} }
@ -418,6 +444,7 @@ void DSDDemod::applySettings(const DSDDemodSettings& settings, bool force)
<< " m_udpAddress: " << m_settings.m_udpAddress << " m_udpAddress: " << m_settings.m_udpAddress
<< " m_udpPort: " << m_settings.m_udpPort << " m_udpPort: " << m_settings.m_udpPort
<< " m_highPassFilter: "<< m_settings.m_highPassFilter << " m_highPassFilter: "<< m_settings.m_highPassFilter
<< " m_audioDeviceName: " << settings.m_audioDeviceName
<< " force: " << force; << " force: " << force;
if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force) if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force)
@ -425,7 +452,7 @@ void DSDDemod::applySettings(const DSDDemodSettings& settings, bool force)
m_settingsMutex.lock(); m_settingsMutex.lock();
m_interpolator.create(16, m_inputSampleRate, (settings.m_rfBandwidth) / 2.2); m_interpolator.create(16, m_inputSampleRate, (settings.m_rfBandwidth) / 2.2);
m_interpolatorDistanceRemain = 0; m_interpolatorDistanceRemain = 0;
m_interpolatorDistance = (Real) m_inputSampleRate / (Real) settings.m_audioSampleRate; m_interpolatorDistance = (Real) m_inputSampleRate / (Real) 48000;
m_phaseDiscri.setFMScaling((float) settings.m_rfBandwidth / (float) settings.m_fmDeviation); m_phaseDiscri.setFMScaling((float) settings.m_rfBandwidth / (float) settings.m_fmDeviation);
m_settingsMutex.unlock(); m_settingsMutex.unlock();
} }
@ -477,6 +504,20 @@ void DSDDemod::applySettings(const DSDDemodSettings& settings, bool force)
m_dsdDecoder.useHPMbelib(settings.m_highPassFilter); m_dsdDecoder.useHPMbelib(settings.m_highPassFilter);
} }
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_audioFifo1, getInputMessageQueue(), audioDeviceIndex);
audioDeviceManager->addAudioSink(&m_audioFifo2, getInputMessageQueue(), audioDeviceIndex);
uint32_t audioSampleRate = audioDeviceManager->getOutputSampleRate(audioDeviceIndex);
if (m_audioSampleRate != audioSampleRate) {
applyAudioSampleRate(audioSampleRate);
}
}
m_settings = settings; m_settings = settings;
} }

View File

@ -163,6 +163,7 @@ private:
int m_inputSampleRate; int m_inputSampleRate;
int m_inputFrequencyOffset; int m_inputFrequencyOffset;
DSDDemodSettings m_settings; DSDDemodSettings m_settings;
quint32 m_audioSampleRate;
NCO m_nco; NCO m_nco;
Interpolator m_interpolator; Interpolator m_interpolator;
@ -200,6 +201,7 @@ private:
static const int m_udpBlockSize; static const int m_udpBlockSize;
void applyAudioSampleRate(int sampleRate);
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force = false); void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force = false);
void applySettings(const DSDDemodSettings& settings, bool force = false); void applySettings(const DSDDemodSettings& settings, bool force = false);
}; };

View File

@ -30,6 +30,8 @@
#include "util/simpleserializer.h" #include "util/simpleserializer.h"
#include "util/db.h" #include "util/db.h"
#include "gui/basicchannelsettingsdialog.h" #include "gui/basicchannelsettingsdialog.h"
#include "gui/crightclickenabler.h"
#include "gui/audioselectdialog.h"
#include "dsp/dspengine.h" #include "dsp/dspengine.h"
#include "mainwindow.h" #include "mainwindow.h"
@ -289,6 +291,9 @@ DSDDemodGUI::DSDDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, Baseban
connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool))); connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &))); connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
CRightClickEnabler *audioMuteRightClickEnabler = new CRightClickEnabler(ui->audioMute);
connect(audioMuteRightClickEnabler, SIGNAL(rightClick()), this, SLOT(audioSelect()));
m_scopeVisXY = new ScopeVisXY(ui->screenTV); m_scopeVisXY = new ScopeVisXY(ui->screenTV);
m_scopeVisXY->setScale(2.0); m_scopeVisXY->setScale(2.0);
m_scopeVisXY->setPixelsPerFrame(4001); m_scopeVisXY->setPixelsPerFrame(4001);
@ -603,6 +608,19 @@ void DSDDemodGUI::channelMarkerHighlightedByCursor()
setHighlighted(m_channelMarker.getHighlighted()); setHighlighted(m_channelMarker.getHighlighted());
} }
void DSDDemodGUI::audioSelect()
{
qDebug("DSDDemodGUI::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 DSDDemodGUI::tick() void DSDDemodGUI::tick()
{ {
double magsqAvg, magsqPeak; double magsqAvg, magsqPeak;

View File

@ -132,6 +132,7 @@ private slots:
void on_symbolPLLLock_toggled(bool checked); void on_symbolPLLLock_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 audioSelect();
void tick(); void tick();
}; };

View File

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

View File

@ -39,7 +39,6 @@ void DSDDemodSettings::resetToDefaults()
m_squelchGate = 5; // 10s of ms at 48000 Hz sample rate. Corresponds to 2400 for AGC attack m_squelchGate = 5; // 10s of ms at 48000 Hz sample rate. Corresponds to 2400 for AGC attack
m_squelch = -40.0; m_squelch = -40.0;
m_audioMute = false; m_audioMute = false;
m_audioSampleRate = DSPEngine::instance()->getDefaultAudioSampleRate();
m_enableCosineFiltering = false; m_enableCosineFiltering = false;
m_syncOrConstellation = false; m_syncOrConstellation = false;
m_slot1On = true; m_slot1On = true;
@ -54,6 +53,7 @@ void DSDDemodSettings::resetToDefaults()
m_traceLengthMutliplier = 6; // 300 ms m_traceLengthMutliplier = 6; // 300 ms
m_traceStroke = 100; m_traceStroke = 100;
m_traceDecay = 200; m_traceDecay = 200;
m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName;
} }
QByteArray DSDDemodSettings::serialize() const QByteArray DSDDemodSettings::serialize() const
@ -85,6 +85,7 @@ QByteArray DSDDemodSettings::serialize() const
s.writeString(18, m_title); s.writeString(18, m_title);
s.writeBool(19, m_highPassFilter); s.writeBool(19, m_highPassFilter);
s.writeString(20, m_audioDeviceName);
s.writeS32(21, m_traceLengthMutliplier); s.writeS32(21, m_traceLengthMutliplier);
s.writeS32(22, m_traceStroke); s.writeS32(22, m_traceStroke);
s.writeS32(23, m_traceDecay); s.writeS32(23, m_traceDecay);
@ -141,6 +142,7 @@ bool DSDDemodSettings::deserialize(const QByteArray& data)
d.readBool(16, &m_tdmaStereo, false); d.readBool(16, &m_tdmaStereo, false);
d.readString(18, &m_title, "DSD Demodulator"); d.readString(18, &m_title, "DSD Demodulator");
d.readBool(19, &m_highPassFilter, false); d.readBool(19, &m_highPassFilter, false);
d.readString(20, &m_audioDeviceName, AudioDeviceManager::m_defaultDeviceName);
d.readS32(21, &tmp, 6); d.readS32(21, &tmp, 6);
m_traceLengthMutliplier = tmp < 2 ? 2 : tmp > 30 ? 30 : tmp; m_traceLengthMutliplier = tmp < 2 ? 2 : tmp > 30 ? 30 : tmp;
d.readS32(22, &tmp, 100); d.readS32(22, &tmp, 100);

View File

@ -32,7 +32,6 @@ struct DSDDemodSettings
int m_squelchGate; int m_squelchGate;
Real m_squelch; Real m_squelch;
bool m_audioMute; bool m_audioMute;
quint32 m_audioSampleRate;
bool m_enableCosineFiltering; bool m_enableCosineFiltering;
bool m_syncOrConstellation; bool m_syncOrConstellation;
bool m_slot1On; bool m_slot1On;
@ -47,6 +46,7 @@ struct DSDDemodSettings
int m_traceLengthMutliplier; // x 50ms int m_traceLengthMutliplier; // x 50ms
int m_traceStroke; // [0..255] int m_traceStroke; // [0..255]
int m_traceDecay; // [0..255] int m_traceDecay; // [0..255]
QString m_audioDeviceName;
Serializable *m_channelMarker; Serializable *m_channelMarker;
Serializable *m_scopeGUI; Serializable *m_scopeGUI;