diff --git a/plugins/channelrx/demodbfm/bfmdemod.cpp b/plugins/channelrx/demodbfm/bfmdemod.cpp index 495ad60a3..593063128 100644 --- a/plugins/channelrx/demodbfm/bfmdemod.cpp +++ b/plugins/channelrx/demodbfm/bfmdemod.cpp @@ -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) diff --git a/plugins/channelrx/demodbfm/bfmdemod.h b/plugins/channelrx/demodbfm/bfmdemod.h index a58ac7216..9c2a9c447 100644 --- a/plugins/channelrx/demodbfm/bfmdemod.h +++ b/plugins/channelrx/demodbfm/bfmdemod.h @@ -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 diff --git a/plugins/channelrx/demodwfm/CMakeLists.txt b/plugins/channelrx/demodwfm/CMakeLists.txt index 625af826b..c088697c2 100644 --- a/plugins/channelrx/demodwfm/CMakeLists.txt +++ b/plugins/channelrx/demodwfm/CMakeLists.txt @@ -1,5 +1,7 @@ project(wfm) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(wfm_SOURCES wfmdemod.cpp wfmdemodgui.cpp diff --git a/plugins/channelrx/demodwfm/wfmdemod.cpp b/plugins/channelrx/demodwfm/wfmdemod.cpp index 5aad81543..d893cd62d 100644 --- a/plugins/channelrx/demodwfm/wfmdemod.cpp +++ b/plugins/channelrx/demodwfm/wfmdemod.cpp @@ -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(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) || - (settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force) + 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; } diff --git a/plugins/channelrx/demodwfm/wfmdemod.h b/plugins/channelrx/demodwfm/wfmdemod.h index 8f8e664dd..a146d8bff 100644 --- a/plugins/channelrx/demodwfm/wfmdemod.h +++ b/plugins/channelrx/demodwfm/wfmdemod.h @@ -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); }; diff --git a/plugins/channelrx/demodwfm/wfmdemodgui.cpp b/plugins/channelrx/demodwfm/wfmdemodgui.cpp index 3280f8420..c81dc4ba6 100644 --- a/plugins/channelrx/demodwfm/wfmdemodgui.cpp +++ b/plugins/channelrx/demodwfm/wfmdemodgui.cpp @@ -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; diff --git a/plugins/channelrx/demodwfm/wfmdemodgui.h b/plugins/channelrx/demodwfm/wfmdemodgui.h index a9b85ba32..34386a0a2 100644 --- a/plugins/channelrx/demodwfm/wfmdemodgui.h +++ b/plugins/channelrx/demodwfm/wfmdemodgui.h @@ -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(); }; diff --git a/plugins/channelrx/demodwfm/wfmdemodgui.ui b/plugins/channelrx/demodwfm/wfmdemodgui.ui index c746145e7..eb99346a5 100644 --- a/plugins/channelrx/demodwfm/wfmdemodgui.ui +++ b/plugins/channelrx/demodwfm/wfmdemodgui.ui @@ -377,6 +377,9 @@ + + Left: audio mute Right: select audio device + diff --git a/plugins/channelrx/demodwfm/wfmdemodsettings.cpp b/plugins/channelrx/demodwfm/wfmdemodsettings.cpp index a9e5edc0c..bbfc66e93 100644 --- a/plugins/channelrx/demodwfm/wfmdemodsettings.cpp +++ b/plugins/channelrx/demodwfm/wfmdemodsettings.cpp @@ -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); diff --git a/plugins/channelrx/demodwfm/wfmdemodsettings.h b/plugins/channelrx/demodwfm/wfmdemodsettings.h index 9c643d12b..c3a3b3180 100644 --- a/plugins/channelrx/demodwfm/wfmdemodsettings.h +++ b/plugins/channelrx/demodwfm/wfmdemodsettings.h @@ -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; diff --git a/plugins/channelrx/demodwfm/wfmplugin.cpp b/plugins/channelrx/demodwfm/wfmplugin.cpp index 062f2490d..98a4c32cb 100644 --- a/plugins/channelrx/demodwfm/wfmplugin.cpp +++ b/plugins/channelrx/demodwfm/wfmplugin.cpp @@ -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,