diff --git a/plugins/channeltx/modam/ammod.cpp b/plugins/channeltx/modam/ammod.cpp index 459d51abc..369cfd048 100644 --- a/plugins/channeltx/modam/ammod.cpp +++ b/plugins/channeltx/modam/ammod.cpp @@ -35,6 +35,7 @@ #include "dsp/dspengine.h" #include "dsp/threadedbasebandsamplesource.h" #include "dsp/dspcommands.h" +#include "dsp/devicesamplemimo.h" #include "device/deviceapi.h" #include "util/db.h" @@ -111,6 +112,11 @@ AMMod::~AMMod() DSPEngine::instance()->getAudioDeviceManager()->removeAudioSource(&m_audioFifo); } +uint32_t AMMod::getNumberOfDeviceStreams() const +{ + return m_deviceAPI->getNbSinkStreams(); +} + void AMMod::pull(Sample& sample) { if (m_settings.m_channelMute) @@ -559,6 +565,7 @@ void AMMod::applySettings(const AMModSettings& settings, bool force) << " m_playLoop: " << settings.m_playLoop << " m_modAFInput " << settings.m_modAFInput << " m_audioDeviceName: " << settings.m_audioDeviceName + << " m_streamIndex: " << settings.m_streamIndex << " m_useReverseAPI: " << settings.m_useReverseAPI << " m_reverseAPIAddress: " << settings.m_reverseAPIAddress << " m_reverseAPIAddress: " << settings.m_reverseAPIPort @@ -639,6 +646,25 @@ void AMMod::applySettings(const AMModSettings& settings, bool force) } } + if (m_settings.m_streamIndex != settings.m_streamIndex) + { + if (m_deviceAPI->getSampleMIMO()) // change of stream is possible for MIMO devices only + { + m_deviceAPI->removeChannelSourceAPI(this, m_settings.m_streamIndex); + m_deviceAPI->removeChannelSource(m_threadedChannelizer, m_settings.m_streamIndex); + m_deviceAPI->addChannelSource(m_threadedChannelizer, settings.m_streamIndex); + m_deviceAPI->addChannelSourceAPI(this, settings.m_streamIndex); + // apply stream sample rate to itself + applyChannelSettings( + m_basebandSampleRate, + m_deviceAPI->getSampleMIMO()->getSinkSampleRate(settings.m_streamIndex), + m_inputFrequencyOffset + ); + } + + reverseAPIKeys.append("streamIndex"); + } + if (settings.m_useReverseAPI) { bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) || diff --git a/plugins/channeltx/modam/ammod.h b/plugins/channeltx/modam/ammod.h index a0de48bf1..d83f0441c 100644 --- a/plugins/channeltx/modam/ammod.h +++ b/plugins/channeltx/modam/ammod.h @@ -252,6 +252,7 @@ public: SWGSDRangel::SWGChannelSettings& response); double getMagSq() const { return m_magsq; } + uint32_t getNumberOfDeviceStreams() const; CWKeyer *getCWKeyer() { return &m_cwKeyer; } diff --git a/plugins/channeltx/modam/ammodgui.cpp b/plugins/channeltx/modam/ammodgui.cpp index beac82d1c..440cadc99 100644 --- a/plugins/channeltx/modam/ammodgui.cpp +++ b/plugins/channeltx/modam/ammodgui.cpp @@ -31,6 +31,7 @@ #include "gui/crightclickenabler.h" #include "gui/audioselectdialog.h" #include "gui/basicchannelsettingsdialog.h" +#include "gui/devicestreamselectiondialog.h" #include "mainwindow.h" #include "ui_ammodgui.h" @@ -317,6 +318,20 @@ void AMModGUI::onMenuDialogCalled(const QPoint &p) applySettings(); } + else if ((m_contextMenuType == ContextMenuStreamSettings) && (m_deviceUISet->m_deviceMIMOEngine)) + { + DeviceStreamSelectionDialog dialog(this); + dialog.setNumberOfStreams(m_amMod->getNumberOfDeviceStreams()); + dialog.setStreamIndex(m_settings.m_streamIndex); + dialog.move(p); + dialog.exec(); + + m_settings.m_streamIndex = dialog.getSelectedStreamIndex(); + m_channelMarker.clearStreamIndexes(); + m_channelMarker.addStreamIndex(m_settings.m_streamIndex); + displayStreamIndex(); + applySettings(); + } resetContextMenuType(); } @@ -460,9 +475,20 @@ void AMModGUI::displaySettings() ui->feedbackVolume->setValue(roundf(m_settings.m_feedbackVolumeFactor * 100.0)); ui->feedbackVolumeText->setText(QString("%1").arg(m_settings.m_feedbackVolumeFactor, 0, 'f', 2)); + displayStreamIndex(); + blockApplySettings(false); } +void AMModGUI::displayStreamIndex() +{ + if (m_deviceUISet->m_deviceMIMOEngine) { + setStreamIndicator(tr("%1").arg(m_settings.m_streamIndex)); + } else { + setStreamIndicator("S"); // single channel indicator + } +} + void AMModGUI::leaveEvent(QEvent*) { m_channelMarker.setHighlighted(false); diff --git a/plugins/channeltx/modam/ammodgui.h b/plugins/channeltx/modam/ammodgui.h index 2e03d76f0..2c6dbcb79 100644 --- a/plugins/channeltx/modam/ammodgui.h +++ b/plugins/channeltx/modam/ammodgui.h @@ -83,6 +83,7 @@ private: void blockApplySettings(bool block); void applySettings(bool force = false); void displaySettings(); + void displayStreamIndex(); void updateWithStreamData(); void updateWithStreamTime(); diff --git a/plugins/channeltx/modam/ammodsettings.cpp b/plugins/channeltx/modam/ammodsettings.cpp index ad044d512..fe2a30d8d 100644 --- a/plugins/channeltx/modam/ammodsettings.cpp +++ b/plugins/channeltx/modam/ammodsettings.cpp @@ -45,6 +45,7 @@ void AMModSettings::resetToDefaults() m_feedbackAudioDeviceName = AudioDeviceManager::m_defaultDeviceName; m_feedbackVolumeFactor = 0.5f; m_feedbackAudioEnable = false; + m_streamIndex = 0; m_useReverseAPI = false; m_reverseAPIAddress = "127.0.0.1"; m_reverseAPIPort = 8888; @@ -84,6 +85,7 @@ QByteArray AMModSettings::serialize() const s.writeString(17, m_feedbackAudioDeviceName); s.writeReal(18, m_feedbackVolumeFactor); s.writeBool(19, m_feedbackAudioEnable); + s.writeS32(20, m_streamIndex); return s.final(); } @@ -151,6 +153,7 @@ bool AMModSettings::deserialize(const QByteArray& data) d.readString(17, &m_feedbackAudioDeviceName, AudioDeviceManager::m_defaultDeviceName); d.readReal(18, &m_feedbackVolumeFactor, 1.0); d.readBool(19, &m_feedbackAudioEnable, false); + d.readS32(20, &m_streamIndex, 0); return true; } diff --git a/plugins/channeltx/modam/ammodsettings.h b/plugins/channeltx/modam/ammodsettings.h index 627a400da..abc5414ea 100644 --- a/plugins/channeltx/modam/ammodsettings.h +++ b/plugins/channeltx/modam/ammodsettings.h @@ -49,6 +49,7 @@ struct AMModSettings QString m_feedbackAudioDeviceName; //!< This is the audio device you send the audio samples to for audio feedback float m_feedbackVolumeFactor; bool m_feedbackAudioEnable; + int m_streamIndex; //!< MIMO channel. Not relevant when connected to SO (single Tx). bool m_useReverseAPI; QString m_reverseAPIAddress; uint16_t m_reverseAPIPort;