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:
parent
44b4b3cc85
commit
c4b092dff0
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user