From 2380211533c7dc309d95cf8e661837086da16d69 Mon Sep 17 00:00:00 2001 From: f4exb Date: Thu, 29 Mar 2018 15:20:38 +0200 Subject: [PATCH] Multiple audio support: AM modulator --- plugins/channeltx/modam/CMakeLists.txt | 2 + plugins/channeltx/modam/ammod.cpp | 74 ++++++++++++++++++----- plugins/channeltx/modam/ammod.h | 2 + plugins/channeltx/modam/ammodgui.cpp | 18 ++++++ plugins/channeltx/modam/ammodgui.h | 1 + plugins/channeltx/modam/ammodgui.ui | 13 +--- plugins/channeltx/modam/ammodsettings.cpp | 4 +- plugins/channeltx/modam/ammodsettings.h | 2 +- plugins/channeltx/modam/readme.md | 6 +- 9 files changed, 92 insertions(+), 30 deletions(-) diff --git a/plugins/channeltx/modam/CMakeLists.txt b/plugins/channeltx/modam/CMakeLists.txt index 0be430f84..7acec8bc9 100644 --- a/plugins/channeltx/modam/CMakeLists.txt +++ b/plugins/channeltx/modam/CMakeLists.txt @@ -1,5 +1,7 @@ project(modam) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(modam_SOURCES ammod.cpp ammodgui.cpp diff --git a/plugins/channeltx/modam/ammod.cpp b/plugins/channeltx/modam/ammod.cpp index 5fbf1cd07..924a04f54 100644 --- a/plugins/channeltx/modam/ammod.cpp +++ b/plugins/channeltx/modam/ammod.cpp @@ -65,11 +65,12 @@ AMMod::AMMod(DeviceSinkAPI *deviceAPI) : m_magsq = 0.0; - m_toneNco.setFreq(1000.0, m_settings.m_audioSampleRate); DSPEngine::instance()->getAudioDeviceManager()->addAudioSource(&m_audioFifo, getInputMessageQueue()); + m_audioSampleRate = DSPEngine::instance()->getAudioDeviceManager()->getInputSampleRate(); + m_toneNco.setFreq(1000.0, m_audioSampleRate); // CW keyer - m_cwKeyer.setSampleRate(m_settings.m_audioSampleRate); + m_cwKeyer.setSampleRate(m_audioSampleRate); m_cwKeyer.setWPM(13); m_cwKeyer.setMode(CWKeyerSettings::CWNone); @@ -139,7 +140,7 @@ void AMMod::pull(Sample& sample) void AMMod::pullAudio(int nbSamples) { // qDebug("AMMod::pullAudio: %d", nbSamples); - unsigned int nbAudioSamples = nbSamples * ((Real) m_settings.m_audioSampleRate / (Real) m_basebandSampleRate); + unsigned int nbAudioSamples = nbSamples * ((Real) m_audioSampleRate / (Real) m_basebandSampleRate); if (nbAudioSamples > m_audioBuffer.size()) { @@ -335,6 +336,20 @@ bool AMMod::handleMessage(const Message& cmd) return true; } + else if (DSPConfigureAudio::match(cmd)) + { + DSPConfigureAudio& cfg = (DSPConfigureAudio&) cmd; + uint32_t sampleRate = cfg.getSampleRate(); + + qDebug() << "AMMod::handleMessage: DSPConfigureAudio:" + << " sampleRate: " << sampleRate; + + if (sampleRate != m_audioSampleRate) { + applyAudioSampleRate(sampleRate); + } + + return true; + } else if (DSPSignalNotification::match(cmd)) { return true; @@ -380,6 +395,28 @@ void AMMod::seekFileStream(int seekPercentage) } } +void AMMod::applyAudioSampleRate(int sampleRate) +{ + qDebug("AMMod::applyAudioSampleRate: %d", sampleRate); + + MsgConfigureChannelizer* channelConfigMsg = MsgConfigureChannelizer::create( + sampleRate, m_settings.m_inputFrequencyOffset); + m_inputMessageQueue.push(channelConfigMsg); + + 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_toneNco.setFreq(m_settings.m_toneFrequency, sampleRate); + m_cwKeyer.setSampleRate(sampleRate); + + m_settingsMutex.unlock(); + + m_audioSampleRate = sampleRate; +} + void AMMod::applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset, bool force) { qDebug() << "AMMod::applyChannelSettings:" @@ -400,8 +437,8 @@ void AMMod::applyChannelSettings(int basebandSampleRate, int outputSampleRate, i 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); m_settingsMutex.unlock(); } @@ -419,30 +456,37 @@ void AMMod::applySettings(const AMModSettings& settings, bool force) << " m_toneFrequency: " << settings.m_toneFrequency << " m_volumeFactor: " << settings.m_volumeFactor << " m_audioMute: " << settings.m_channelMute - << " m_playLoop: " << settings.m_playLoop; + << " m_playLoop: " << settings.m_playLoop + << " m_audioDeviceName: " << settings.m_audioDeviceName + << " force: " << force; - if((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || - (settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force) + if((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || 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(); } - if ((settings.m_toneFrequency != m_settings.m_toneFrequency) || - (settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force) + if ((settings.m_toneFrequency != m_settings.m_toneFrequency) || force) { m_settingsMutex.lock(); - m_toneNco.setFreq(settings.m_toneFrequency, settings.m_audioSampleRate); + m_toneNco.setFreq(settings.m_toneFrequency, m_audioSampleRate); m_settingsMutex.unlock(); } - if ((settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force) + if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force) { - m_cwKeyer.setSampleRate(settings.m_audioSampleRate); + 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/modam/ammod.h b/plugins/channeltx/modam/ammod.h index 1ed8d3651..b0152069d 100644 --- a/plugins/channeltx/modam/ammod.h +++ b/plugins/channeltx/modam/ammod.h @@ -276,6 +276,7 @@ private: int m_outputSampleRate; int m_inputFrequencyOffset; AMModSettings m_settings; + quint32 m_audioSampleRate; NCO m_carrierNco; NCOF m_toneNco; @@ -309,6 +310,7 @@ private: static const int m_levelNbSamples; + void applyAudioSampleRate(int sampleRate); void applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset, bool force = false); void applySettings(const AMModSettings& settings, bool force = false); void pullAF(Real& sample); diff --git a/plugins/channeltx/modam/ammodgui.cpp b/plugins/channeltx/modam/ammodgui.cpp index 79027a693..2ee194a90 100644 --- a/plugins/channeltx/modam/ammodgui.cpp +++ b/plugins/channeltx/modam/ammodgui.cpp @@ -31,6 +31,8 @@ #include "util/simpleserializer.h" #include "util/db.h" #include "dsp/dspengine.h" +#include "gui/crightclickenabler.h" +#include "gui/audioselectdialog.h" #include "mainwindow.h" AMModGUI* AMModGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSource *channelTx) @@ -282,6 +284,9 @@ AMModGUI::AMModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampl 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); @@ -391,6 +396,19 @@ void AMModGUI::enterEvent(QEvent*) m_channelMarker.setHighlighted(true); } +void AMModGUI::audioSelect() +{ + qDebug("AMModGUI::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 AMModGUI::tick() { double powDb = CalcDb::dbPower(m_amMod->getMagSq()); diff --git a/plugins/channeltx/modam/ammodgui.h b/plugins/channeltx/modam/ammodgui.h index 82b4efbf3..fcccb2c69 100644 --- a/plugins/channeltx/modam/ammodgui.h +++ b/plugins/channeltx/modam/ammodgui.h @@ -110,6 +110,7 @@ private slots: void onWidgetRolled(QWidget* widget, bool rollDown); void configureFileName(); + void audioSelect(); void tick(); }; diff --git a/plugins/channeltx/modam/ammodgui.ui b/plugins/channeltx/modam/ammodgui.ui index 1b98dafa4..4321def42 100644 --- a/plugins/channeltx/modam/ammodgui.ui +++ b/plugins/channeltx/modam/ammodgui.ui @@ -56,16 +56,7 @@ 3 - - 2 - - - 2 - - - 2 - - + 2 @@ -449,7 +440,7 @@ - Audio input + Left: Source audio input Right: Select audio input device ... diff --git a/plugins/channeltx/modam/ammodsettings.cpp b/plugins/channeltx/modam/ammodsettings.cpp index bee3ed0d8..aaaf572be 100644 --- a/plugins/channeltx/modam/ammodsettings.cpp +++ b/plugins/channeltx/modam/ammodsettings.cpp @@ -34,12 +34,12 @@ void AMModSettings::resetToDefaults() m_rfBandwidth = 12500.0; m_modFactor = 0.2f; m_toneFrequency = 1000.0f; - m_audioSampleRate = DSPEngine::instance()->getDefaultAudioSampleRate(); m_volumeFactor = 1.0f; m_channelMute = false; m_playLoop = false; m_rgbColor = QColor(255, 255, 0).rgb(); m_title = "AM Modulator"; + m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName; } QByteArray AMModSettings::serialize() const @@ -62,6 +62,7 @@ QByteArray AMModSettings::serialize() const } s.writeString(9, m_title); + s.writeString(10, m_audioDeviceName); return s.final(); } @@ -100,6 +101,7 @@ bool AMModSettings::deserialize(const QByteArray& data) } d.readString(9, &m_title, "AM Modulator"); + d.readString(10, &m_audioDeviceName, AudioDeviceManager::m_defaultDeviceName); return true; } diff --git a/plugins/channeltx/modam/ammodsettings.h b/plugins/channeltx/modam/ammodsettings.h index ab915d7bc..6aadcf6e3 100644 --- a/plugins/channeltx/modam/ammodsettings.h +++ b/plugins/channeltx/modam/ammodsettings.h @@ -28,11 +28,11 @@ struct AMModSettings float m_modFactor; 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; diff --git a/plugins/channeltx/modam/readme.md b/plugins/channeltx/modam/readme.md index 9f766ec36..b401c0ec2 100644 --- a/plugins/channeltx/modam/readme.md +++ b/plugins/channeltx/modam/readme.md @@ -56,9 +56,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 -

9.4: Audio input select

+

9.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.

10: CW (Morse) text