From 75201ad303cbfa501e23cf9fbeb0b807cc57bbb8 Mon Sep 17 00:00:00 2001 From: f4exb Date: Thu, 29 Mar 2018 17:27:03 +0200 Subject: [PATCH] Multiple audio support: WFM modulator --- plugins/channeltx/modwfm/CMakeLists.txt | 2 + plugins/channeltx/modwfm/readme.md | 6 ++- plugins/channeltx/modwfm/wfmmod.cpp | 59 +++++++++++++++++---- plugins/channeltx/modwfm/wfmmod.h | 3 +- plugins/channeltx/modwfm/wfmmodgui.cpp | 18 +++++++ plugins/channeltx/modwfm/wfmmodgui.h | 1 + plugins/channeltx/modwfm/wfmmodsettings.cpp | 4 +- plugins/channeltx/modwfm/wfmmodsettings.h | 2 +- 8 files changed, 81 insertions(+), 14 deletions(-) diff --git a/plugins/channeltx/modwfm/CMakeLists.txt b/plugins/channeltx/modwfm/CMakeLists.txt index d712b8597..7f28858d4 100644 --- a/plugins/channeltx/modwfm/CMakeLists.txt +++ b/plugins/channeltx/modwfm/CMakeLists.txt @@ -1,5 +1,7 @@ project(modwfm) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(modwfm_SOURCES wfmmod.cpp wfmmodgui.cpp diff --git a/plugins/channeltx/modwfm/readme.md b/plugins/channeltx/modwfm/readme.md index 1ce694997..51b6a2cb2 100644 --- a/plugins/channeltx/modwfm/readme.md +++ b/plugins/channeltx/modwfm/readme.md @@ -60,9 +60,11 @@ Switches to the Morse keyer input. You must switch it off to make other inputs a Adjusts the tone frequency from 0.1 to 2.5 kHz in 0.01 kHz steps -

10.4: Audio input select

+

10.4: Audio input select and select audio input device

-Switches to the audio input. You must switch it off to make other inputs available. +Left click to switch to the audio input. You must switch it off to make other inputs available. + +Right click to select audio input device.

11: CW (Morse) text

diff --git a/plugins/channeltx/modwfm/wfmmod.cpp b/plugins/channeltx/modwfm/wfmmod.cpp index b78be126c..14dfcaf80 100644 --- a/plugins/channeltx/modwfm/wfmmod.cpp +++ b/plugins/channeltx/modwfm/wfmmod.cpp @@ -73,9 +73,10 @@ WFMMod::WFMMod(DeviceSinkAPI *deviceAPI) : m_magsq = 0.0; - m_toneNco.setFreq(1000.0, m_settings.m_audioSampleRate); - m_toneNcoRF.setFreq(1000.0, m_outputSampleRate); DSPEngine::instance()->getAudioDeviceManager()->addAudioSource(&m_audioFifo, getInputMessageQueue()); + m_audioSampleRate = DSPEngine::instance()->getAudioDeviceManager()->getInputSampleRate(); + + m_toneNcoRF.setFreq(1000.0, m_outputSampleRate); // CW keyer m_cwKeyer.setSampleRate(m_outputSampleRate); @@ -164,7 +165,7 @@ void WFMMod::pull(Sample& sample) void WFMMod::pullAudio(int nbSamples) { - unsigned int nbSamplesAudio = nbSamples * ((Real) m_settings.m_audioSampleRate / (Real) m_basebandSampleRate); + unsigned int nbSamplesAudio = nbSamples * ((Real) m_audioSampleRate / (Real) m_basebandSampleRate); if (nbSamplesAudio > m_audioBuffer.size()) { @@ -359,6 +360,20 @@ bool WFMMod::handleMessage(const Message& cmd) return true; } + else if (DSPConfigureAudio::match(cmd)) + { + DSPConfigureAudio& cfg = (DSPConfigureAudio&) cmd; + uint32_t sampleRate = cfg.getSampleRate(); + + qDebug() << "WFMMod::handleMessage: DSPConfigureAudio:" + << " sampleRate: " << sampleRate; + + if (sampleRate != m_audioSampleRate) { + applyAudioSampleRate(sampleRate); + } + + return true; + } else if (DSPSignalNotification::match(cmd)) { return true; @@ -404,6 +419,20 @@ void WFMMod::seekFileStream(int seekPercentage) } } +void WFMMod::applyAudioSampleRate(int sampleRate) +{ + qDebug("WFMMod::applyAudioSampleRate: %d", sampleRate); + + m_settingsMutex.lock(); + m_interpolatorDistanceRemain = 0; + m_interpolatorConsumed = false; + m_interpolatorDistance = (Real) sampleRate / (Real) m_outputSampleRate; + m_interpolator.create(48, sampleRate, m_settings.m_rfBandwidth / 2.2, 3.0); + m_settingsMutex.unlock(); + + m_audioSampleRate = sampleRate; +} + void WFMMod::applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset, bool force) { qDebug() << "WFMMod::applyChannelSettings:" @@ -424,8 +453,8 @@ void WFMMod::applyChannelSettings(int basebandSampleRate, int outputSampleRate, m_settingsMutex.lock(); m_interpolatorDistanceRemain = 0; m_interpolatorConsumed = false; - m_interpolatorDistance = (Real) m_settings.m_audioSampleRate / (Real) outputSampleRate; - m_interpolator.create(48, m_settings.m_audioSampleRate, m_settings.m_rfBandwidth / 2.2, 3.0); + m_interpolatorDistance = (Real) m_audioSampleRate / (Real) outputSampleRate; + m_interpolator.create(48, m_audioSampleRate, m_settings.m_rfBandwidth / 2.2, 3.0); Real lowCut = -(m_settings.m_rfBandwidth / 2.0) / outputSampleRate; Real hiCut = (m_settings.m_rfBandwidth / 2.0) / outputSampleRate; m_rfFilter->create_filter(lowCut, hiCut); @@ -451,16 +480,16 @@ void WFMMod::applySettings(const WFMModSettings& settings, bool force) << " m_toneFrequency: " << settings.m_toneFrequency << " m_channelMute: " << settings.m_channelMute << " m_playLoop: " << settings.m_playLoop + << " m_audioDeviceName: " << settings.m_audioDeviceName << " force: " << force; - if((settings.m_audioSampleRate != m_settings.m_audioSampleRate) || - (settings.m_afBandwidth != m_settings.m_afBandwidth) || force) + if((settings.m_afBandwidth != m_settings.m_afBandwidth) || force) { m_settingsMutex.lock(); m_interpolatorDistanceRemain = 0; m_interpolatorConsumed = false; - m_interpolatorDistance = (Real) settings.m_audioSampleRate / (Real) m_outputSampleRate; - m_interpolator.create(48, settings.m_audioSampleRate, settings.m_rfBandwidth / 2.2, 3.0); + m_interpolatorDistance = (Real) m_audioSampleRate / (Real) m_outputSampleRate; + m_interpolator.create(48, m_audioSampleRate, settings.m_rfBandwidth / 2.2, 3.0); m_settingsMutex.unlock(); } @@ -480,6 +509,18 @@ void WFMMod::applySettings(const WFMModSettings& settings, bool force) m_settingsMutex.unlock(); } + if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force) + { + AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager(); + int audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_audioDeviceName); + audioDeviceManager->addAudioSource(&m_audioFifo, getInputMessageQueue(), audioDeviceIndex); + uint32_t audioSampleRate = audioDeviceManager->getInputSampleRate(audioDeviceIndex); + + if (m_audioSampleRate != audioSampleRate) { + applyAudioSampleRate(audioSampleRate); + } + } + m_settings = settings; } diff --git a/plugins/channeltx/modwfm/wfmmod.h b/plugins/channeltx/modwfm/wfmmod.h index b324c79dc..d47608181 100644 --- a/plugins/channeltx/modwfm/wfmmod.h +++ b/plugins/channeltx/modwfm/wfmmod.h @@ -277,9 +277,9 @@ private: int m_outputSampleRate; int m_inputFrequencyOffset; WFMModSettings m_settings; + quint32 m_audioSampleRate; NCO m_carrierNco; - NCOF m_toneNco; NCOF m_toneNcoRF; float m_modPhasor; //!< baseband modulator phasor Complex m_modSample; @@ -316,6 +316,7 @@ private: CWKeyer m_cwKeyer; static const int m_levelNbSamples; + void applyAudioSampleRate(int sampleRate); void applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset, bool force = false); void applySettings(const WFMModSettings& settings, bool force = false); void pullAF(Complex& sample); diff --git a/plugins/channeltx/modwfm/wfmmodgui.cpp b/plugins/channeltx/modwfm/wfmmodgui.cpp index d6a62b91a..aaf6d9ac6 100644 --- a/plugins/channeltx/modwfm/wfmmodgui.cpp +++ b/plugins/channeltx/modwfm/wfmmodgui.cpp @@ -28,6 +28,8 @@ #include "util/simpleserializer.h" #include "util/db.h" #include "dsp/dspengine.h" +#include "gui/crightclickenabler.h" +#include "gui/audioselectdialog.h" #include "mainwindow.h" #include "ui_wfmmodgui.h" @@ -299,6 +301,9 @@ WFMModGUI::WFMModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam connect(&MainWindow::getInstance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick())); + CRightClickEnabler *audioMuteRightClickEnabler = new CRightClickEnabler(ui->mic); + 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); @@ -411,6 +416,19 @@ void WFMModGUI::enterEvent(QEvent*) m_channelMarker.setHighlighted(true); } +void WFMModGUI::audioSelect() +{ + qDebug("WFMModGUI::audioSelect"); + AudioSelectDialog audioSelect(DSPEngine::instance()->getAudioDeviceManager(), m_settings.m_audioDeviceName, true); // true for input + audioSelect.exec(); + + if (audioSelect.m_selected) + { + m_settings.m_audioDeviceName = audioSelect.m_audioDeviceName; + applySettings(); + } +} + void WFMModGUI::tick() { double powDb = CalcDb::dbPower(m_wfmMod->getMagSq()); diff --git a/plugins/channeltx/modwfm/wfmmodgui.h b/plugins/channeltx/modwfm/wfmmodgui.h index aca95366b..1dc64de3c 100644 --- a/plugins/channeltx/modwfm/wfmmodgui.h +++ b/plugins/channeltx/modwfm/wfmmodgui.h @@ -122,6 +122,7 @@ private slots: void onWidgetRolled(QWidget* widget, bool rollDown); void configureFileName(); + void audioSelect(); void tick(); }; diff --git a/plugins/channeltx/modwfm/wfmmodsettings.cpp b/plugins/channeltx/modwfm/wfmmodsettings.cpp index afae3d54c..b4d596c80 100644 --- a/plugins/channeltx/modwfm/wfmmodsettings.cpp +++ b/plugins/channeltx/modwfm/wfmmodsettings.cpp @@ -42,12 +42,12 @@ void WFMModSettings::resetToDefaults() m_afBandwidth = 15000.0f; m_fmDeviation = 50000.0f; m_toneFrequency = 1000.0f; - m_audioSampleRate = DSPEngine::instance()->getDefaultAudioSampleRate(); m_volumeFactor = 1.0f; m_channelMute = false; m_playLoop = false; m_rgbColor = QColor(0, 0, 255).rgb(); m_title = "WFM Modulator"; + m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName; } QByteArray WFMModSettings::serialize() const @@ -71,6 +71,7 @@ QByteArray WFMModSettings::serialize() const } s.writeString(10, m_title); + s.writeString(11, m_audioDeviceName); return s.final(); } @@ -110,6 +111,7 @@ bool WFMModSettings::deserialize(const QByteArray& data) } d.readString(10, &m_title, "WFM Modulator"); + d.readString(11, &m_audioDeviceName, AudioDeviceManager::m_defaultDeviceName); return true; } diff --git a/plugins/channeltx/modwfm/wfmmodsettings.h b/plugins/channeltx/modwfm/wfmmodsettings.h index f83b8cf22..2b1cff3fe 100644 --- a/plugins/channeltx/modwfm/wfmmodsettings.h +++ b/plugins/channeltx/modwfm/wfmmodsettings.h @@ -32,11 +32,11 @@ struct WFMModSettings float m_fmDeviation; float m_toneFrequency; float m_volumeFactor; - quint32 m_audioSampleRate; bool m_channelMute; bool m_playLoop; quint32 m_rgbColor; QString m_title; + QString m_audioDeviceName; Serializable *m_channelMarker; Serializable *m_cwKeyerGUI;