mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-31 04:50:29 -04:00 
			
		
		
		
	Channel Rx plugins: implement MIMO support
This commit is contained in:
		
							parent
							
								
									c9eb8a8ec0
								
							
						
					
					
						commit
						51a07c3f7b
					
				| @ -37,6 +37,7 @@ | ||||
| #include "dsp/downchannelizer.h" | ||||
| #include "dsp/threadedbasebandsamplesink.h" | ||||
| #include "dsp/dspcommands.h" | ||||
| #include "dsp/devicesamplemimo.h" | ||||
| #include "device/deviceapi.h" | ||||
| #include "util/db.h" | ||||
| 
 | ||||
| @ -124,6 +125,11 @@ BFMDemod::~BFMDemod() | ||||
|     delete m_rfFilter; | ||||
| } | ||||
| 
 | ||||
| uint32_t BFMDemod::getNumberOfDeviceStreams() const | ||||
| { | ||||
|     return m_deviceAPI->getNbSourceStreams(); | ||||
| } | ||||
| 
 | ||||
| void BFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) | ||||
| { | ||||
|     (void) firstOfBurst; | ||||
| @ -460,6 +466,7 @@ void BFMDemod::applySettings(const BFMDemodSettings& settings, bool force) | ||||
|             << " m_showPilot: " << settings.m_showPilot | ||||
|             << " m_rdsActive: " << settings.m_rdsActive | ||||
|             << " m_audioDeviceName: " << settings.m_audioDeviceName | ||||
|             << " m_streamIndex: " << settings.m_streamIndex | ||||
|             << " m_useReverseAPI: " << settings.m_useReverseAPI | ||||
|             << " force: " << force; | ||||
| 
 | ||||
| @ -542,6 +549,21 @@ void BFMDemod::applySettings(const BFMDemodSettings& 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->removeChannelSinkAPI(this, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->removeChannelSink(m_threadedChannelizer, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSink(m_threadedChannelizer, settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSinkAPI(this, settings.m_streamIndex); | ||||
|             // apply stream sample rate to itself
 | ||||
|             applyChannelSettings(m_deviceAPI->getSampleMIMO()->getSourceSampleRate(settings.m_streamIndex), m_inputFrequencyOffset); | ||||
|         } | ||||
| 
 | ||||
|         reverseAPIKeys.append("streamIndex"); | ||||
|     } | ||||
| 
 | ||||
|     if (settings.m_useReverseAPI) | ||||
|     { | ||||
|         bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) || | ||||
| @ -661,6 +683,9 @@ void BFMDemod::webapiUpdateChannelSettings( | ||||
|     if (channelSettingsKeys.contains("audioDeviceName")) { | ||||
|         settings.m_audioDeviceName = *response.getBfmDemodSettings()->getAudioDeviceName(); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex")) { | ||||
|         settings.m_streamIndex = response.getBfmDemodSettings()->getStreamIndex(); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("useReverseAPI")) { | ||||
|         settings.m_useReverseAPI = response.getBfmDemodSettings()->getUseReverseApi() != 0; | ||||
|     } | ||||
| @ -714,6 +739,7 @@ void BFMDemod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& resp | ||||
|         response.getBfmDemodSettings()->setAudioDeviceName(new QString(settings.m_audioDeviceName)); | ||||
|     } | ||||
| 
 | ||||
|     response.getBfmDemodSettings()->setStreamIndex(settings.m_streamIndex); | ||||
|     response.getBfmDemodSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); | ||||
| 
 | ||||
|     if (response.getBfmDemodSettings()->getReverseApiAddress()) { | ||||
| @ -827,6 +853,9 @@ void BFMDemod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, co | ||||
|     if (channelSettingsKeys.contains("audioDeviceName") || force) { | ||||
|         swgBFMDemodSettings->setAudioDeviceName(new QString(settings.m_audioDeviceName)); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex") || force) { | ||||
|         swgBFMDemodSettings->setStreamIndex(settings.m_streamIndex); | ||||
|     } | ||||
| 
 | ||||
|     QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings") | ||||
|             .arg(settings.m_reverseAPIAddress) | ||||
|  | ||||
| @ -212,6 +212,8 @@ public: | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     uint32_t getNumberOfDeviceStreams() const; | ||||
| 
 | ||||
|     static const QString m_channelIdURI; | ||||
|     static const QString m_channelId; | ||||
| 
 | ||||
|  | ||||
| @ -36,6 +36,7 @@ | ||||
| #include "util/simpleserializer.h" | ||||
| #include "util/db.h" | ||||
| #include "gui/basicchannelsettingsdialog.h" | ||||
| #include "gui/devicestreamselectiondialog.h" | ||||
| #include "gui/crightclickenabler.h" | ||||
| #include "gui/audioselectdialog.h" | ||||
| #include "mainwindow.h" | ||||
| @ -344,6 +345,20 @@ void BFMDemodGUI::onMenuDialogCalled(const QPoint &p) | ||||
| 
 | ||||
|         applySettings(); | ||||
|     } | ||||
|     else if ((m_contextMenuType == ContextMenuStreamSettings) && (m_deviceUISet->m_deviceMIMOEngine)) | ||||
|     { | ||||
|         DeviceStreamSelectionDialog dialog(this); | ||||
|         dialog.setNumberOfStreams(m_bfmDemod->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(); | ||||
| } | ||||
| @ -483,9 +498,20 @@ void BFMDemodGUI::displaySettings() | ||||
|     ui->showPilot->setChecked(m_settings.m_showPilot); | ||||
|     ui->rds->setChecked(m_settings.m_rdsActive); | ||||
| 
 | ||||
|     displayStreamIndex(); | ||||
| 
 | ||||
|     blockApplySettings(false); | ||||
| } | ||||
| 
 | ||||
| void BFMDemodGUI::displayStreamIndex() | ||||
| { | ||||
|     if (m_deviceUISet->m_deviceMIMOEngine) { | ||||
|         setStreamIndicator(tr("%1").arg(m_settings.m_streamIndex)); | ||||
|     } else { | ||||
|         setStreamIndicator("S"); // single channel indicator
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void BFMDemodGUI::leaveEvent(QEvent*) | ||||
| { | ||||
| 	m_channelMarker.setHighlighted(false); | ||||
|  | ||||
| @ -81,6 +81,7 @@ private: | ||||
|     void blockApplySettings(bool block); | ||||
| 	void applySettings(bool force = false); | ||||
|     void displaySettings(); | ||||
|     void displayStreamIndex(); | ||||
| 	void rdsUpdate(bool force); | ||||
| 	void rdsUpdateFixedFields(); | ||||
| 
 | ||||
|  | ||||
| @ -49,6 +49,7 @@ void BFMDemodSettings::resetToDefaults() | ||||
|     m_rgbColor = QColor(80, 120, 228).rgb(); | ||||
|     m_title = "Broadcast FM Demod"; | ||||
|     m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName; | ||||
|     m_streamIndex = 0; | ||||
|     m_useReverseAPI = false; | ||||
|     m_reverseAPIAddress = "127.0.0.1"; | ||||
|     m_reverseAPIPort = 8888; | ||||
| @ -84,6 +85,7 @@ QByteArray BFMDemodSettings::serialize() const | ||||
|     s.writeU32(16, m_reverseAPIPort); | ||||
|     s.writeU32(17, m_reverseAPIDeviceIndex); | ||||
|     s.writeU32(18, m_reverseAPIChannelIndex); | ||||
|     s.writeS32(19, m_streamIndex); | ||||
| 
 | ||||
|     return s.final(); | ||||
| } | ||||
| @ -148,6 +150,7 @@ bool BFMDemodSettings::deserialize(const QByteArray& data) | ||||
|         m_reverseAPIDeviceIndex = utmp > 99 ? 99 : utmp; | ||||
|         d.readU32(18, &utmp, 0); | ||||
|         m_reverseAPIChannelIndex = utmp > 99 ? 99 : utmp; | ||||
|         d.readS32(19, &m_streamIndex, 0); | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| @ -36,6 +36,7 @@ struct BFMDemodSettings | ||||
|     quint32 m_rgbColor; | ||||
|     QString m_title; | ||||
|     QString m_audioDeviceName; | ||||
|     int m_streamIndex; //!< MIMO channel. Not relevant when connected to SI (single Rx).
 | ||||
|     bool m_useReverseAPI; | ||||
|     QString m_reverseAPIAddress; | ||||
|     uint16_t m_reverseAPIPort; | ||||
|  | ||||
| @ -38,6 +38,7 @@ | ||||
| #include "dsp/threadedbasebandsamplesink.h" | ||||
| #include "dsp/downchannelizer.h" | ||||
| #include "dsp/dspcommands.h" | ||||
| #include "dsp/devicesamplemimo.h" | ||||
| #include "device/deviceapi.h" | ||||
| #include "util/db.h" | ||||
| 
 | ||||
| @ -122,6 +123,11 @@ void DSDDemod::configureMyPosition(MessageQueue* messageQueue, float myLatitude, | ||||
| 	messageQueue->push(cmd); | ||||
| } | ||||
| 
 | ||||
| uint32_t DSDDemod::getNumberOfDeviceStreams() const | ||||
| { | ||||
|     return m_deviceAPI->getNbSourceStreams(); | ||||
| } | ||||
| 
 | ||||
| void DSDDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) | ||||
| { | ||||
|     (void) firstOfBurst; | ||||
| @ -492,6 +498,7 @@ void DSDDemod::applySettings(const DSDDemodSettings& settings, bool force) | ||||
|             << " m_traceLengthMutliplier: " << settings.m_traceLengthMutliplier | ||||
|             << " m_traceStroke: " << settings.m_traceStroke | ||||
|             << " m_traceDecay: " << settings.m_traceDecay | ||||
|             << " m_streamIndex: " << settings.m_streamIndex | ||||
|             << " force: " << force; | ||||
| 
 | ||||
|     QList<QString> reverseAPIKeys; | ||||
| @ -603,6 +610,21 @@ void DSDDemod::applySettings(const DSDDemodSettings& 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->removeChannelSinkAPI(this, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->removeChannelSink(m_threadedChannelizer, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSink(m_threadedChannelizer, settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSinkAPI(this, settings.m_streamIndex); | ||||
|             // apply stream sample rate to itself
 | ||||
|             applyChannelSettings(m_deviceAPI->getSampleMIMO()->getSourceSampleRate(settings.m_streamIndex), m_inputFrequencyOffset); | ||||
|         } | ||||
| 
 | ||||
|         reverseAPIKeys.append("streamIndex"); | ||||
|     } | ||||
| 
 | ||||
|     if (settings.m_useReverseAPI) | ||||
|     { | ||||
|         bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) || | ||||
| @ -941,6 +963,9 @@ void DSDDemod::webapiUpdateChannelSettings( | ||||
|     if (channelSettingsKeys.contains("traceDecay")) { | ||||
|         settings.m_traceDecay = response.getDsdDemodSettings()->getTraceDecay(); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex")) { | ||||
|         settings.m_streamIndex = response.getDsdDemodSettings()->getStreamIndex(); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("useReverseAPI")) { | ||||
|         settings.m_useReverseAPI = response.getDsdDemodSettings()->getUseReverseApi() != 0; | ||||
|     } | ||||
| @ -1004,6 +1029,7 @@ void DSDDemod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& resp | ||||
|     response.getDsdDemodSettings()->setTraceLengthMutliplier(settings.m_traceLengthMutliplier); | ||||
|     response.getDsdDemodSettings()->setTraceStroke(settings.m_traceStroke); | ||||
|     response.getDsdDemodSettings()->setTraceDecay(settings.m_traceDecay); | ||||
|     response.getDsdDemodSettings()->setStreamIndex(settings.m_streamIndex); | ||||
|     response.getDsdDemodSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); | ||||
| 
 | ||||
|     if (response.getDsdDemodSettings()->getReverseApiAddress()) { | ||||
| @ -1117,6 +1143,9 @@ void DSDDemod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, co | ||||
|     if (channelSettingsKeys.contains("traceDecay") || force) { | ||||
|         swgDSDDemodSettings->setTraceDecay(settings.m_traceDecay); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex") || force) { | ||||
|         swgDSDDemodSettings->setStreamIndex(settings.m_streamIndex); | ||||
|     } | ||||
| 
 | ||||
|     QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings") | ||||
|             .arg(settings.m_reverseAPIAddress) | ||||
|  | ||||
| @ -173,6 +173,8 @@ public: | ||||
|             const QStringList& channelSettingsKeys, | ||||
|             SWGSDRangel::SWGChannelSettings& response); | ||||
| 
 | ||||
|     uint32_t getNumberOfDeviceStreams() const; | ||||
| 
 | ||||
|     static const QString m_channelIdURI; | ||||
|     static const QString m_channelId; | ||||
| 
 | ||||
|  | ||||
| @ -28,6 +28,7 @@ | ||||
| #include "util/simpleserializer.h" | ||||
| #include "util/db.h" | ||||
| #include "gui/basicchannelsettingsdialog.h" | ||||
| #include "gui/devicestreamselectiondialog.h" | ||||
| #include "gui/crightclickenabler.h" | ||||
| #include "gui/audioselectdialog.h" | ||||
| #include "dsp/dspengine.h" | ||||
| @ -298,6 +299,20 @@ void DSDDemodGUI::onMenuDialogCalled(const QPoint &p) | ||||
| 
 | ||||
|         applySettings(); | ||||
|     } | ||||
|     else if ((m_contextMenuType == ContextMenuStreamSettings) && (m_deviceUISet->m_deviceMIMOEngine)) | ||||
|     { | ||||
|         DeviceStreamSelectionDialog dialog(this); | ||||
|         dialog.setNumberOfStreams(m_dsdDemod->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(); | ||||
| } | ||||
| @ -465,9 +480,20 @@ void DSDDemodGUI::displaySettings() | ||||
|     ui->traceDecayText->setText(QString("%1").arg(m_settings.m_traceDecay)); | ||||
|     m_scopeVisXY->setDecay(m_settings.m_traceDecay); | ||||
| 
 | ||||
|     displayStreamIndex(); | ||||
| 
 | ||||
|     blockApplySettings(false); | ||||
| } | ||||
| 
 | ||||
| void DSDDemodGUI::displayStreamIndex() | ||||
| { | ||||
|     if (m_deviceUISet->m_deviceMIMOEngine) { | ||||
|         setStreamIndicator(tr("%1").arg(m_settings.m_streamIndex)); | ||||
|     } else { | ||||
|         setStreamIndicator("S"); // single channel indicator
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void DSDDemodGUI::applySettings(bool force) | ||||
| { | ||||
| 	if (m_doApplySettings) | ||||
|  | ||||
| @ -106,6 +106,7 @@ private: | ||||
| 	void blockApplySettings(bool block); | ||||
| 	void applySettings(bool force = false); | ||||
|     void displaySettings(); | ||||
|     void displayStreamIndex(); | ||||
| 	void updateMyPosition(); | ||||
| 
 | ||||
| 	void leaveEvent(QEvent*); | ||||
|  | ||||
| @ -53,6 +53,7 @@ void DSDDemodSettings::resetToDefaults() | ||||
|     m_traceStroke = 100; | ||||
|     m_traceDecay = 200; | ||||
|     m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName; | ||||
|     m_streamIndex = 0; | ||||
|     m_useReverseAPI = false; | ||||
|     m_reverseAPIAddress = "127.0.0.1"; | ||||
|     m_reverseAPIPort = 8888; | ||||
| @ -100,6 +101,7 @@ QByteArray DSDDemodSettings::serialize() const | ||||
|     s.writeU32(27, m_reverseAPIDeviceIndex); | ||||
|     s.writeU32(28, m_reverseAPIChannelIndex); | ||||
|     s.writeBool(29, m_audioMute); | ||||
|     s.writeS32(30, m_streamIndex); | ||||
| 
 | ||||
|     return s.final(); | ||||
| } | ||||
| @ -177,6 +179,7 @@ bool DSDDemodSettings::deserialize(const QByteArray& data) | ||||
|         d.readU32(28, &utmp, 0); | ||||
|         m_reverseAPIChannelIndex = utmp > 99 ? 99 : utmp; | ||||
|         d.readBool(29, &m_audioMute, false); | ||||
|         d.readS32(30, &m_streamIndex, 0); | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| @ -46,6 +46,7 @@ struct DSDDemodSettings | ||||
|     int m_traceStroke; // [0..255]
 | ||||
|     int m_traceDecay; // [0..255]
 | ||||
|     QString m_audioDeviceName; | ||||
|     int m_streamIndex; //!< MIMO channel. Not relevant when connected to SI (single Rx).
 | ||||
|     bool m_useReverseAPI; | ||||
|     QString m_reverseAPIAddress; | ||||
|     uint16_t m_reverseAPIPort; | ||||
|  | ||||
| @ -36,6 +36,7 @@ | ||||
| #include "dsp/downchannelizer.h" | ||||
| #include "dsp/threadedbasebandsamplesink.h" | ||||
| #include "dsp/dspcommands.h" | ||||
| #include "dsp/devicesamplemimo.h" | ||||
| #include "device/deviceapi.h" | ||||
| #include "util/db.h" | ||||
| 
 | ||||
| @ -252,6 +253,11 @@ void FreeDVDemod::configure(MessageQueue* messageQueue, | ||||
| 	messageQueue->push(cmd); | ||||
| } | ||||
| 
 | ||||
| uint32_t FreeDVDemod::getNumberOfDeviceStreams() const | ||||
| { | ||||
|     return m_deviceAPI->getNbSourceStreams(); | ||||
| } | ||||
| 
 | ||||
| void FreeDVDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly) | ||||
| { | ||||
|     (void) positiveOnly; | ||||
| @ -715,6 +721,7 @@ void FreeDVDemod::applySettings(const FreeDVDemodSettings& settings, bool force) | ||||
|             << " m_audioMute: " << settings.m_audioMute | ||||
|             << " m_agcActive: " << settings.m_agc | ||||
|             << " m_audioDeviceName: " << settings.m_audioDeviceName | ||||
|             << " m_streamIndex: " << settings.m_streamIndex | ||||
|             << " m_useReverseAPI: " << settings.m_useReverseAPI | ||||
|             << " m_reverseAPIAddress: " << settings.m_reverseAPIAddress | ||||
|             << " m_reverseAPIPort: " << settings.m_reverseAPIPort | ||||
| @ -771,6 +778,21 @@ void FreeDVDemod::applySettings(const FreeDVDemodSettings& settings, bool force) | ||||
|     m_audioMute = settings.m_audioMute; | ||||
|     m_agcActive = settings.m_agc; | ||||
| 
 | ||||
|     if (m_settings.m_streamIndex != settings.m_streamIndex) | ||||
|     { | ||||
|         if (m_deviceAPI->getSampleMIMO()) // change of stream is possible for MIMO devices only
 | ||||
|         { | ||||
|             m_deviceAPI->removeChannelSinkAPI(this, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->removeChannelSink(m_threadedChannelizer, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSink(m_threadedChannelizer, settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSinkAPI(this, settings.m_streamIndex); | ||||
|             // apply stream sample rate to itself
 | ||||
|             applyChannelSettings(m_deviceAPI->getSampleMIMO()->getSourceSampleRate(settings.m_streamIndex), m_inputFrequencyOffset); | ||||
|         } | ||||
| 
 | ||||
|         reverseAPIKeys.append("streamIndex"); | ||||
|     } | ||||
| 
 | ||||
|     if (settings.m_useReverseAPI) | ||||
|     { | ||||
|         bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) || | ||||
| @ -901,6 +923,9 @@ void FreeDVDemod::webapiUpdateChannelSettings( | ||||
|     if (channelSettingsKeys.contains("audioDeviceName")) { | ||||
|         settings.m_audioDeviceName = *response.getFreeDvDemodSettings()->getAudioDeviceName(); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex")) { | ||||
|         settings.m_streamIndex = response.getFreeDvDemodSettings()->getStreamIndex(); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("useReverseAPI")) { | ||||
|         settings.m_useReverseAPI = response.getFreeDvDemodSettings()->getUseReverseApi() != 0; | ||||
|     } | ||||
| @ -953,6 +978,7 @@ void FreeDVDemod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& r | ||||
|         response.getFreeDvDemodSettings()->setAudioDeviceName(new QString(settings.m_audioDeviceName)); | ||||
|     } | ||||
| 
 | ||||
|     response.getFreeDvDemodSettings()->setStreamIndex(settings.m_streamIndex); | ||||
|     response.getFreeDvDemodSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); | ||||
| 
 | ||||
|     if (response.getFreeDvDemodSettings()->getReverseApiAddress()) { | ||||
| @ -1020,6 +1046,9 @@ void FreeDVDemod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, | ||||
|     if (channelSettingsKeys.contains("audioDeviceName") || force) { | ||||
|         swgFreeDVDemodSettings->setAudioDeviceName(new QString(settings.m_audioDeviceName)); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex") || force) { | ||||
|         swgFreeDVDemodSettings->setStreamIndex(settings.m_streamIndex); | ||||
|     } | ||||
| 
 | ||||
|     QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings") | ||||
|             .arg(settings.m_reverseAPIAddress) | ||||
|  | ||||
| @ -203,6 +203,8 @@ public: | ||||
|             const QStringList& channelSettingsKeys, | ||||
|             SWGSDRangel::SWGChannelSettings& response); | ||||
| 
 | ||||
|     uint32_t getNumberOfDeviceStreams() const; | ||||
| 
 | ||||
|     static const QString m_channelIdURI; | ||||
|     static const QString m_channelId; | ||||
| 
 | ||||
|  | ||||
| @ -26,6 +26,7 @@ | ||||
| #include "dsp/dspcommands.h" | ||||
| #include "gui/glspectrum.h" | ||||
| #include "gui/basicchannelsettingsdialog.h" | ||||
| #include "gui/devicestreamselectiondialog.h" | ||||
| #include "plugin/pluginapi.h" | ||||
| #include "util/simpleserializer.h" | ||||
| #include "util/db.h" | ||||
| @ -232,6 +233,20 @@ void FreeDVDemodGUI::onMenuDialogCalled(const QPoint &p) | ||||
| 
 | ||||
|         applySettings(); | ||||
|     } | ||||
|     else if ((m_contextMenuType == ContextMenuStreamSettings) && (m_deviceUISet->m_deviceMIMOEngine)) | ||||
|     { | ||||
|         DeviceStreamSelectionDialog dialog(this); | ||||
|         dialog.setNumberOfStreams(m_freeDVDemod->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(); | ||||
| } | ||||
| @ -399,9 +414,20 @@ void FreeDVDemodGUI::displaySettings() | ||||
|     ui->volumeIn->setValue(m_settings.m_volumeIn * 10.0); | ||||
|     ui->volumeInText->setText(QString("%1").arg(m_settings.m_volumeIn, 0, 'f', 1)); | ||||
| 
 | ||||
|     displayStreamIndex(); | ||||
| 
 | ||||
|     blockApplySettings(false); | ||||
| } | ||||
| 
 | ||||
| void FreeDVDemodGUI::displayStreamIndex() | ||||
| { | ||||
|     if (m_deviceUISet->m_deviceMIMOEngine) { | ||||
|         setStreamIndicator(tr("%1").arg(m_settings.m_streamIndex)); | ||||
|     } else { | ||||
|         setStreamIndicator("S"); // single channel indicator
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void FreeDVDemodGUI::leaveEvent(QEvent*) | ||||
| { | ||||
| 	m_channelMarker.setHighlighted(false); | ||||
|  | ||||
| @ -90,6 +90,7 @@ private: | ||||
| 	void applyBandwidths(int spanLog2, bool force = false); | ||||
| 	void displayBandwidths(int spanLog2); | ||||
| 	void displaySettings(); | ||||
|     void displayStreamIndex(); | ||||
| 
 | ||||
| 	void leaveEvent(QEvent*); | ||||
| 	void enterEvent(QEvent*); | ||||
|  | ||||
| @ -49,6 +49,7 @@ void FreeDVDemodSettings::resetToDefaults() | ||||
|     m_title = "FreeDV Demodulator"; | ||||
|     m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName; | ||||
|     m_freeDVMode = FreeDVMode2400A; | ||||
|     m_streamIndex = 0; | ||||
|     m_useReverseAPI = false; | ||||
|     m_reverseAPIAddress = "127.0.0.1"; | ||||
|     m_reverseAPIPort = 8888; | ||||
| @ -78,6 +79,7 @@ QByteArray FreeDVDemodSettings::serialize() const | ||||
|     s.writeU32(21, m_reverseAPIDeviceIndex); | ||||
|     s.writeU32(22, m_reverseAPIChannelIndex); | ||||
|     s.writeS32(23, (int) m_freeDVMode); | ||||
|     s.writeS32(24, m_streamIndex); | ||||
| 
 | ||||
|     return s.final(); | ||||
| } | ||||
| @ -138,6 +140,8 @@ bool FreeDVDemodSettings::deserialize(const QByteArray& data) | ||||
|             m_freeDVMode = (FreeDVMode) tmp; | ||||
|         } | ||||
| 
 | ||||
|         d.readS32(24, &m_streamIndex, 0); | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
|     else | ||||
|  | ||||
| @ -45,6 +45,7 @@ struct FreeDVDemodSettings | ||||
|     QString m_title; | ||||
|     QString m_audioDeviceName; | ||||
|     FreeDVMode m_freeDVMode; | ||||
|     int m_streamIndex; //!< MIMO channel. Not relevant when connected to SI (single Rx).
 | ||||
|     bool m_useReverseAPI; | ||||
|     QString m_reverseAPIAddress; | ||||
|     uint16_t m_reverseAPIPort; | ||||
|  | ||||
| @ -37,6 +37,7 @@ | ||||
| #include "dsp/dspengine.h" | ||||
| #include "dsp/threadedbasebandsamplesink.h" | ||||
| #include "dsp/dspcommands.h" | ||||
| #include "dsp/devicesamplemimo.h" | ||||
| #include "device/deviceapi.h" | ||||
| 
 | ||||
| #include "nfmdemod.h" | ||||
| @ -147,6 +148,11 @@ Real angleDist(Real a, Real b) | ||||
| 	return dist; | ||||
| } | ||||
| 
 | ||||
| uint32_t NFMDemod::getNumberOfDeviceStreams() const | ||||
| { | ||||
|     return m_deviceAPI->getNbSourceStreams(); | ||||
| } | ||||
| 
 | ||||
| void NFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) | ||||
| { | ||||
|     (void) firstOfBurst; | ||||
| @ -521,6 +527,7 @@ void NFMDemod::applySettings(const NFMDemodSettings& settings, bool force) | ||||
|             << " m_highPass: " << settings.m_highPass | ||||
|             << " m_audioMute: " << settings.m_audioMute | ||||
|             << " m_audioDeviceName: " << settings.m_audioDeviceName | ||||
|             << " m_streamIndex: " << settings.m_streamIndex | ||||
|             << " m_useReverseAPI: " << settings.m_useReverseAPI | ||||
|             << " m_reverseAPIAddress: " << settings.m_reverseAPIAddress | ||||
|             << " m_reverseAPIPort: " << settings.m_reverseAPIPort | ||||
| @ -630,6 +637,21 @@ void NFMDemod::applySettings(const NFMDemodSettings& 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->removeChannelSinkAPI(this, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->removeChannelSink(m_threadedChannelizer, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSink(m_threadedChannelizer, settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSinkAPI(this, settings.m_streamIndex); | ||||
|             // apply stream sample rate to itself
 | ||||
|             applyChannelSettings(m_deviceAPI->getSampleMIMO()->getSourceSampleRate(settings.m_streamIndex), m_inputFrequencyOffset); | ||||
|         } | ||||
| 
 | ||||
|         reverseAPIKeys.append("streamIndex"); | ||||
|     } | ||||
| 
 | ||||
|     if (settings.m_useReverseAPI) | ||||
|     { | ||||
|         bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) || | ||||
| @ -760,6 +782,9 @@ void NFMDemod::webapiUpdateChannelSettings( | ||||
|     if (channelSettingsKeys.contains("audioDeviceName")) { | ||||
|         settings.m_audioDeviceName = *response.getNfmDemodSettings()->getAudioDeviceName(); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex")) { | ||||
|         settings.m_streamIndex = response.getNfmDemodSettings()->getStreamIndex(); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("useReverseAPI")) { | ||||
|         settings.m_useReverseAPI = response.getNfmDemodSettings()->getUseReverseApi() != 0; | ||||
|     } | ||||
| @ -816,6 +841,7 @@ void NFMDemod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& resp | ||||
|         response.getNfmDemodSettings()->setAudioDeviceName(new QString(settings.m_audioDeviceName)); | ||||
|     } | ||||
| 
 | ||||
|     response.getNfmDemodSettings()->setStreamIndex(settings.m_streamIndex); | ||||
|     response.getNfmDemodSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); | ||||
| 
 | ||||
|     if (response.getNfmDemodSettings()->getReverseApiAddress()) { | ||||
| @ -899,6 +925,9 @@ void NFMDemod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, co | ||||
|     if (channelSettingsKeys.contains("audioDeviceName") || force) { | ||||
|         swgNFMDemodSettings->setAudioDeviceName(new QString(settings.m_audioDeviceName)); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex") || force) { | ||||
|         swgNFMDemodSettings->setStreamIndex(settings.m_streamIndex); | ||||
|     } | ||||
| 
 | ||||
|     QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings") | ||||
|             .arg(settings.m_reverseAPIAddress) | ||||
|  | ||||
| @ -195,6 +195,8 @@ public: | ||||
|         m_magsqCount = 0; | ||||
|     } | ||||
| 
 | ||||
|     uint32_t getNumberOfDeviceStreams() const; | ||||
| 
 | ||||
|     static const QString m_channelIdURI; | ||||
|     static const QString m_channelId; | ||||
| 
 | ||||
|  | ||||
| @ -10,6 +10,7 @@ | ||||
| #include "util/simpleserializer.h" | ||||
| #include "util/db.h" | ||||
| #include "gui/basicchannelsettingsdialog.h" | ||||
| #include "gui/devicestreamselectiondialog.h" | ||||
| #include "gui/crightclickenabler.h" | ||||
| #include "gui/audioselectdialog.h" | ||||
| #include "dsp/dspengine.h" | ||||
| @ -256,6 +257,20 @@ void NFMDemodGUI::onMenuDialogCalled(const QPoint &p) | ||||
| 
 | ||||
|         applySettings(); | ||||
|     } | ||||
|     else if ((m_contextMenuType == ContextMenuStreamSettings) && (m_deviceUISet->m_deviceMIMOEngine)) | ||||
|     { | ||||
|         DeviceStreamSelectionDialog dialog(this); | ||||
|         dialog.setNumberOfStreams(m_nfmDemod->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(); | ||||
| } | ||||
| @ -409,9 +424,20 @@ void NFMDemodGUI::displaySettings() | ||||
| 
 | ||||
|     ui->ctcss->setCurrentIndex(m_settings.m_ctcssIndex); | ||||
| 
 | ||||
|     displayStreamIndex(); | ||||
| 
 | ||||
|     blockApplySettings(false); | ||||
| } | ||||
| 
 | ||||
| void NFMDemodGUI::displayStreamIndex() | ||||
| { | ||||
|     if (m_deviceUISet->m_deviceMIMOEngine) { | ||||
|         setStreamIndicator(tr("%1").arg(m_settings.m_streamIndex)); | ||||
|     } else { | ||||
|         setStreamIndicator("S"); // single channel indicator
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void NFMDemodGUI::leaveEvent(QEvent*) | ||||
| { | ||||
| 	m_channelMarker.setHighlighted(false); | ||||
|  | ||||
| @ -62,6 +62,7 @@ private: | ||||
| 	void blockApplySettings(bool block); | ||||
| 	void applySettings(bool force = false); | ||||
| 	void displaySettings(); | ||||
|     void displayStreamIndex(); | ||||
| 
 | ||||
| 	void leaveEvent(QEvent*); | ||||
| 	void enterEvent(QEvent*); | ||||
|  | ||||
| @ -54,6 +54,7 @@ void NFMDemodSettings::resetToDefaults() | ||||
|     m_title = "NFM Demodulator"; | ||||
|     m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName; | ||||
|     m_highPass = true; | ||||
|     m_streamIndex = 0; | ||||
|     m_useReverseAPI = false; | ||||
|     m_reverseAPIAddress = "127.0.0.1"; | ||||
|     m_reverseAPIPort = 8888; | ||||
| @ -88,6 +89,7 @@ QByteArray NFMDemodSettings::serialize() const | ||||
|     s.writeU32(18, m_reverseAPIPort); | ||||
|     s.writeU32(19, m_reverseAPIDeviceIndex); | ||||
|     s.writeU32(20, m_reverseAPIChannelIndex); | ||||
|     s.writeS32(21, m_streamIndex); | ||||
| 
 | ||||
|     return s.final(); | ||||
| } | ||||
| @ -148,6 +150,7 @@ bool NFMDemodSettings::deserialize(const QByteArray& data) | ||||
|         m_reverseAPIDeviceIndex = utmp > 99 ? 99 : utmp; | ||||
|         d.readU32(20, &utmp, 0); | ||||
|         m_reverseAPIChannelIndex = utmp > 99 ? 99 : utmp; | ||||
|         d.readS32(21, &m_streamIndex, 0); | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| @ -43,6 +43,7 @@ struct NFMDemodSettings | ||||
|     QString m_title; | ||||
|     QString m_audioDeviceName; | ||||
|     bool m_highPass; | ||||
|     int m_streamIndex; //!< MIMO channel. Not relevant when connected to SI (single Rx).
 | ||||
|     bool m_useReverseAPI; | ||||
|     QString m_reverseAPIAddress; | ||||
|     uint16_t m_reverseAPIPort; | ||||
|  | ||||
| @ -36,6 +36,7 @@ | ||||
| #include "dsp/downchannelizer.h" | ||||
| #include "dsp/threadedbasebandsamplesink.h" | ||||
| #include "dsp/dspcommands.h" | ||||
| #include "dsp/devicesamplemimo.h" | ||||
| #include "device/deviceapi.h" | ||||
| #include "util/db.h" | ||||
| 
 | ||||
| @ -154,6 +155,11 @@ void SSBDemod::configure(MessageQueue* messageQueue, | ||||
| 	messageQueue->push(cmd); | ||||
| } | ||||
| 
 | ||||
| uint32_t SSBDemod::getNumberOfDeviceStreams() const | ||||
| { | ||||
|     return m_deviceAPI->getNbSourceStreams(); | ||||
| } | ||||
| 
 | ||||
| void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly) | ||||
| { | ||||
|     (void) positiveOnly; | ||||
| @ -473,6 +479,7 @@ void SSBDemod::applySettings(const SSBDemodSettings& settings, bool force) | ||||
|             << " agcPowerThreshold: " << settings.m_agcPowerThreshold | ||||
|             << " agcThresholdGate: " << settings.m_agcThresholdGate | ||||
|             << " m_audioDeviceName: " << settings.m_audioDeviceName | ||||
|             << " m_streamIndex: " << settings.m_streamIndex | ||||
|             << " m_useReverseAPI: " << settings.m_useReverseAPI | ||||
|             << " m_reverseAPIAddress: " << settings.m_reverseAPIAddress | ||||
|             << " m_reverseAPIPort: " << settings.m_reverseAPIPort | ||||
| @ -631,6 +638,21 @@ void SSBDemod::applySettings(const SSBDemodSettings& settings, bool force) | ||||
|     m_audioMute = settings.m_audioMute; | ||||
|     m_agcActive = settings.m_agc; | ||||
| 
 | ||||
|     if (m_settings.m_streamIndex != settings.m_streamIndex) | ||||
|     { | ||||
|         if (m_deviceAPI->getSampleMIMO()) // change of stream is possible for MIMO devices only
 | ||||
|         { | ||||
|             m_deviceAPI->removeChannelSinkAPI(this, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->removeChannelSink(m_threadedChannelizer, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSink(m_threadedChannelizer, settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSinkAPI(this, settings.m_streamIndex); | ||||
|             // apply stream sample rate to itself
 | ||||
|             applyChannelSettings(m_deviceAPI->getSampleMIMO()->getSourceSampleRate(settings.m_streamIndex), m_inputFrequencyOffset); | ||||
|         } | ||||
| 
 | ||||
|         reverseAPIKeys.append("streamIndex"); | ||||
|     } | ||||
| 
 | ||||
|     if (settings.m_useReverseAPI) | ||||
|     { | ||||
|         bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) || | ||||
| @ -765,6 +787,9 @@ void SSBDemod::webapiUpdateChannelSettings( | ||||
|     if (channelSettingsKeys.contains("audioDeviceName")) { | ||||
|         settings.m_audioDeviceName = *response.getSsbDemodSettings()->getAudioDeviceName(); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex")) { | ||||
|         settings.m_streamIndex = response.getSsbDemodSettings()->getStreamIndex(); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("useReverseAPI")) { | ||||
|         settings.m_useReverseAPI = response.getSsbDemodSettings()->getUseReverseApi() != 0; | ||||
|     } | ||||
| @ -824,6 +849,7 @@ void SSBDemod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& resp | ||||
|         response.getSsbDemodSettings()->setAudioDeviceName(new QString(settings.m_audioDeviceName)); | ||||
|     } | ||||
| 
 | ||||
|     response.getSsbDemodSettings()->setStreamIndex(settings.m_streamIndex); | ||||
|     response.getSsbDemodSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); | ||||
| 
 | ||||
|     if (response.getSsbDemodSettings()->getReverseApiAddress()) { | ||||
| @ -912,6 +938,9 @@ void SSBDemod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, co | ||||
|     if (channelSettingsKeys.contains("audioDeviceName") || force) { | ||||
|         swgSSBDemodSettings->setAudioDeviceName(new QString(settings.m_audioDeviceName)); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex") || force) { | ||||
|         swgSSBDemodSettings->setStreamIndex(settings.m_streamIndex); | ||||
|     } | ||||
| 
 | ||||
|     QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings") | ||||
|             .arg(settings.m_reverseAPIAddress) | ||||
|  | ||||
| @ -182,6 +182,8 @@ public: | ||||
|             const QStringList& channelSettingsKeys, | ||||
|             SWGSDRangel::SWGChannelSettings& response); | ||||
| 
 | ||||
|     uint32_t getNumberOfDeviceStreams() const; | ||||
| 
 | ||||
|     static const QString m_channelIdURI; | ||||
|     static const QString m_channelId; | ||||
| 
 | ||||
|  | ||||
| @ -10,6 +10,7 @@ | ||||
| #include "dsp/dspcommands.h" | ||||
| #include "gui/glspectrum.h" | ||||
| #include "gui/basicchannelsettingsdialog.h" | ||||
| #include "gui/devicestreamselectiondialog.h" | ||||
| #include "plugin/pluginapi.h" | ||||
| #include "util/simpleserializer.h" | ||||
| #include "util/db.h" | ||||
| @ -262,6 +263,20 @@ void SSBDemodGUI::onMenuDialogCalled(const QPoint &p) | ||||
| 
 | ||||
|         applySettings(); | ||||
|     } | ||||
|     else if ((m_contextMenuType == ContextMenuStreamSettings) && (m_deviceUISet->m_deviceMIMOEngine)) | ||||
|     { | ||||
|         DeviceStreamSelectionDialog dialog(this); | ||||
|         dialog.setNumberOfStreams(m_ssbDemod->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(); | ||||
| } | ||||
| @ -568,9 +583,20 @@ void SSBDemodGUI::displaySettings() | ||||
|     displayAGCPowerThreshold(ui->agcPowerThreshold->value()); | ||||
|     displayAGCThresholdGate(m_settings.m_agcThresholdGate); | ||||
| 
 | ||||
|     displayStreamIndex(); | ||||
| 
 | ||||
|     blockApplySettings(false); | ||||
| } | ||||
| 
 | ||||
| void SSBDemodGUI::displayStreamIndex() | ||||
| { | ||||
|     if (m_deviceUISet->m_deviceMIMOEngine) { | ||||
|         setStreamIndicator(tr("%1").arg(m_settings.m_streamIndex)); | ||||
|     } else { | ||||
|         setStreamIndicator("S"); // single channel indicator
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void SSBDemodGUI::displayAGCPowerThreshold(int value) | ||||
| { | ||||
|     if (value == SSBDemodSettings::m_minPowerThresholdDB) | ||||
|  | ||||
| @ -73,6 +73,7 @@ private: | ||||
| 	void applyBandwidths(int spanLog2, bool force = false); | ||||
|     int spanLog2Limit(int spanLog2); | ||||
| 	void displaySettings(); | ||||
|     void displayStreamIndex(); | ||||
| 	void displayAGCPowerThreshold(int value); | ||||
|     void displayAGCThresholdGate(int value); | ||||
| 
 | ||||
|  | ||||
| @ -56,6 +56,7 @@ void SSBDemodSettings::resetToDefaults() | ||||
|     m_rgbColor = QColor(0, 255, 0).rgb(); | ||||
|     m_title = "SSB Demodulator"; | ||||
|     m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName; | ||||
|     m_streamIndex = 0; | ||||
|     m_useReverseAPI = false; | ||||
|     m_reverseAPIAddress = "127.0.0.1"; | ||||
|     m_reverseAPIPort = 8888; | ||||
| @ -92,6 +93,7 @@ QByteArray SSBDemodSettings::serialize() const | ||||
|     s.writeU32(20, m_reverseAPIPort); | ||||
|     s.writeU32(21, m_reverseAPIDeviceIndex); | ||||
|     s.writeU32(22, m_reverseAPIChannelIndex); | ||||
|     s.writeS32(23, m_streamIndex); | ||||
| 
 | ||||
|     return s.final(); | ||||
| } | ||||
| @ -152,6 +154,7 @@ bool SSBDemodSettings::deserialize(const QByteArray& data) | ||||
|         m_reverseAPIDeviceIndex = utmp > 99 ? 99 : utmp; | ||||
|         d.readU32(22, &utmp, 0); | ||||
|         m_reverseAPIChannelIndex = utmp > 99 ? 99 : utmp; | ||||
|         d.readS32(23, &m_streamIndex, 0); | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| @ -41,6 +41,7 @@ struct SSBDemodSettings | ||||
|     quint32 m_rgbColor; | ||||
|     QString m_title; | ||||
|     QString m_audioDeviceName; | ||||
|     int m_streamIndex; //!< MIMO channel. Not relevant when connected to SI (single Rx).
 | ||||
|     bool m_useReverseAPI; | ||||
|     QString m_reverseAPIAddress; | ||||
|     uint16_t m_reverseAPIPort; | ||||
|  | ||||
| @ -37,6 +37,8 @@ | ||||
| #include "audio/audiooutput.h" | ||||
| #include "dsp/dspengine.h" | ||||
| #include "dsp/dspcommands.h" | ||||
| #include "dsp/devicesamplemimo.h" | ||||
| #include "device/deviceapi.h" | ||||
| #include "util/db.h" | ||||
| 
 | ||||
| #include "wfmdemod.h" | ||||
| @ -97,6 +99,11 @@ WFMDemod::~WFMDemod() | ||||
|     delete m_rfFilter; | ||||
| } | ||||
| 
 | ||||
| uint32_t WFMDemod::getNumberOfDeviceStreams() const | ||||
| { | ||||
|     return m_deviceAPI->getNbSourceStreams(); | ||||
| } | ||||
| 
 | ||||
| void WFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) | ||||
| { | ||||
|     (void) firstOfBurst; | ||||
| @ -328,6 +335,7 @@ void WFMDemod::applySettings(const WFMDemodSettings& settings, bool force) | ||||
|             << " m_squelch: " << settings.m_squelch | ||||
|             << " m_audioDeviceName: " << settings.m_audioDeviceName | ||||
|             << " m_audioMute: " << settings.m_audioMute | ||||
|             << " m_streamIndex: " << settings.m_streamIndex | ||||
|             << " m_useReverseAPI: " << settings.m_useReverseAPI | ||||
|             << " m_reverseAPIAddress: " << settings.m_reverseAPIAddress | ||||
|             << " m_reverseAPIPort: " << settings.m_reverseAPIPort | ||||
| @ -402,6 +410,21 @@ void WFMDemod::applySettings(const WFMDemodSettings& 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->removeChannelSinkAPI(this, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->removeChannelSink(m_threadedChannelizer, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSink(m_threadedChannelizer, settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSinkAPI(this, settings.m_streamIndex); | ||||
|             // apply stream sample rate to itself
 | ||||
|             applyChannelSettings(m_deviceAPI->getSampleMIMO()->getSourceSampleRate(settings.m_streamIndex), m_inputFrequencyOffset); | ||||
|         } | ||||
| 
 | ||||
|         reverseAPIKeys.append("streamIndex"); | ||||
|     } | ||||
| 
 | ||||
|     if (settings.m_useReverseAPI) | ||||
|     { | ||||
|         bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) || | ||||
| @ -512,6 +535,9 @@ void WFMDemod::webapiUpdateChannelSettings( | ||||
|     if (channelSettingsKeys.contains("audioDeviceName")) { | ||||
|         settings.m_audioDeviceName = *response.getWfmDemodSettings()->getAudioDeviceName(); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex")) { | ||||
|         settings.m_streamIndex = response.getWfmDemodSettings()->getStreamIndex(); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("useReverseAPI")) { | ||||
|         settings.m_useReverseAPI = response.getWfmDemodSettings()->getUseReverseApi() != 0; | ||||
|     } | ||||
| @ -562,6 +588,7 @@ void WFMDemod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& resp | ||||
|         response.getWfmDemodSettings()->setAudioDeviceName(new QString(settings.m_audioDeviceName)); | ||||
|     } | ||||
| 
 | ||||
|     response.getWfmDemodSettings()->setStreamIndex(settings.m_streamIndex); | ||||
|     response.getWfmDemodSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); | ||||
| 
 | ||||
|     if (response.getWfmDemodSettings()->getReverseApiAddress()) { | ||||
| @ -626,6 +653,9 @@ void WFMDemod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, co | ||||
|     if (channelSettingsKeys.contains("audioDeviceName") || force) { | ||||
|         swgWFMDemodSettings->setAudioDeviceName(new QString(settings.m_audioDeviceName)); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex") || force) { | ||||
|         swgWFMDemodSettings->setStreamIndex(settings.m_streamIndex); | ||||
|     } | ||||
| 
 | ||||
|     QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings") | ||||
|             .arg(settings.m_reverseAPIAddress) | ||||
|  | ||||
| @ -173,6 +173,8 @@ public: | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     uint32_t getNumberOfDeviceStreams() const; | ||||
| 
 | ||||
|     static const QString m_channelIdURI; | ||||
|     static const QString m_channelId; | ||||
| 
 | ||||
|  | ||||
| @ -13,6 +13,7 @@ | ||||
| #include "util/simpleserializer.h" | ||||
| #include "util/db.h" | ||||
| #include "gui/basicchannelsettingsdialog.h" | ||||
| #include "gui/devicestreamselectiondialog.h" | ||||
| #include "gui/crightclickenabler.h" | ||||
| #include "gui/audioselectdialog.h" | ||||
| #include "mainwindow.h" | ||||
| @ -194,6 +195,20 @@ void WFMDemodGUI::onMenuDialogCalled(const QPoint &p) | ||||
| 
 | ||||
|         applySettings(); | ||||
|     } | ||||
|     else if ((m_contextMenuType == ContextMenuStreamSettings) && (m_deviceUISet->m_deviceMIMOEngine)) | ||||
|     { | ||||
|         DeviceStreamSelectionDialog dialog(this); | ||||
|         dialog.setNumberOfStreams(m_wfmDemod->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(); | ||||
| } | ||||
| @ -301,9 +316,20 @@ void WFMDemodGUI::displaySettings() | ||||
|     ui->squelchText->setText(QString("%1 dB").arg(m_settings.m_squelch)); | ||||
|     ui->audioMute->setChecked(m_settings.m_audioMute); | ||||
| 
 | ||||
|     displayStreamIndex(); | ||||
| 
 | ||||
|     blockApplySettings(false); | ||||
| } | ||||
| 
 | ||||
| void WFMDemodGUI::displayStreamIndex() | ||||
| { | ||||
|     if (m_deviceUISet->m_deviceMIMOEngine) { | ||||
|         setStreamIndicator(tr("%1").arg(m_settings.m_streamIndex)); | ||||
|     } else { | ||||
|         setStreamIndicator("S"); // single channel indicator
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void WFMDemodGUI::leaveEvent(QEvent*) | ||||
| { | ||||
| 	m_channelMarker.setHighlighted(false); | ||||
|  | ||||
| @ -59,6 +59,7 @@ private: | ||||
|     void blockApplySettings(bool block); | ||||
| 	void applySettings(bool force = false); | ||||
| 	void displaySettings(); | ||||
| 	void displayStreamIndex(); | ||||
| 
 | ||||
| 	void leaveEvent(QEvent*); | ||||
| 	void enterEvent(QEvent*); | ||||
|  | ||||
| @ -45,6 +45,7 @@ void WFMDemodSettings::resetToDefaults() | ||||
|     m_rgbColor = QColor(0, 0, 255).rgb(); | ||||
|     m_title = "WFM Demodulator"; | ||||
|     m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName; | ||||
|     m_streamIndex = 0; | ||||
|     m_useReverseAPI = false; | ||||
|     m_reverseAPIAddress = "127.0.0.1"; | ||||
|     m_reverseAPIPort = 8888; | ||||
| @ -73,6 +74,7 @@ QByteArray WFMDemodSettings::serialize() const | ||||
|     s.writeU32(14, m_reverseAPIPort); | ||||
|     s.writeU32(15, m_reverseAPIDeviceIndex); | ||||
|     s.writeU32(16, m_reverseAPIChannelIndex); | ||||
|     s.writeS32(17, m_streamIndex); | ||||
| 
 | ||||
|     return s.final(); | ||||
| } | ||||
| @ -128,6 +130,7 @@ bool WFMDemodSettings::deserialize(const QByteArray& data) | ||||
|         m_reverseAPIDeviceIndex = utmp > 99 ? 99 : utmp; | ||||
|         d.readU32(16, &utmp, 0); | ||||
|         m_reverseAPIChannelIndex = utmp > 99 ? 99 : utmp; | ||||
|         d.readS32(17, &m_streamIndex, 0); | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| @ -34,6 +34,7 @@ struct WFMDemodSettings | ||||
|     quint32 m_rgbColor; | ||||
|     QString m_title; | ||||
|     QString m_audioDeviceName; | ||||
|     int m_streamIndex; //!< MIMO channel. Not relevant when connected to SI (single Rx).
 | ||||
|     bool m_useReverseAPI; | ||||
|     QString m_reverseAPIAddress; | ||||
|     uint16_t m_reverseAPIPort; | ||||
|  | ||||
| @ -38,6 +38,7 @@ | ||||
| #include "dsp/threadedbasebandsamplesink.h" | ||||
| #include "dsp/dspcommands.h" | ||||
| #include "dsp/fftfilt.h" | ||||
| #include "dsp/devicesamplemimo.h" | ||||
| #include "device/deviceapi.h" | ||||
| #include "util/db.h" | ||||
| #include "util/stepfunctions.h" | ||||
| @ -109,6 +110,11 @@ FreqTracker::~FreqTracker() | ||||
|     delete m_rrcFilter; | ||||
| } | ||||
| 
 | ||||
| uint32_t FreqTracker::getNumberOfDeviceStreams() const | ||||
| { | ||||
|     return m_deviceAPI->getNbSourceStreams(); | ||||
| } | ||||
| 
 | ||||
| void FreqTracker::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) | ||||
| { | ||||
|     (void) firstOfBurst; | ||||
| @ -333,6 +339,7 @@ void FreqTracker::applySettings(const FreqTrackerSettings& settings, bool force) | ||||
|                 << " m_pllPskOrder: " << settings.m_pllPskOrder | ||||
|                 << " m_rrc: " << settings.m_rrc | ||||
|                 << " m_rrcRolloff: " << settings.m_rrcRolloff | ||||
|                 << " m_streamIndex: " << settings.m_streamIndex | ||||
|                 << " m_useReverseAPI: " << settings.m_useReverseAPI | ||||
|                 << " m_reverseAPIAddress: " << settings.m_reverseAPIAddress | ||||
|                 << " m_reverseAPIPort: " << settings.m_reverseAPIPort | ||||
| @ -434,6 +441,21 @@ void FreqTracker::applySettings(const FreqTrackerSettings& settings, bool force) | ||||
|         updateInterpolator = true; | ||||
|     } | ||||
| 
 | ||||
|     if (m_settings.m_streamIndex != settings.m_streamIndex) | ||||
|     { | ||||
|         if (m_deviceAPI->getSampleMIMO()) // change of stream is possible for MIMO devices only
 | ||||
|         { | ||||
|             m_deviceAPI->removeChannelSinkAPI(this, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->removeChannelSink(m_threadedChannelizer, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSink(m_threadedChannelizer, settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSinkAPI(this, settings.m_streamIndex); | ||||
|             // apply stream sample rate to itself
 | ||||
|             applyChannelSettings(m_deviceAPI->getSampleMIMO()->getSourceSampleRate(settings.m_streamIndex), m_inputFrequencyOffset); | ||||
|         } | ||||
| 
 | ||||
|         reverseAPIKeys.append("streamIndex"); | ||||
|     } | ||||
| 
 | ||||
|     if (settings.m_useReverseAPI) | ||||
|     { | ||||
|         bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) || | ||||
| @ -618,6 +640,9 @@ void FreqTracker::webapiUpdateChannelSettings( | ||||
|     if (channelSettingsKeys.contains("squelchGate")) { | ||||
|         settings.m_squelchGate = response.getFreqTrackerSettings()->getSquelchGate(); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex")) { | ||||
|         settings.m_streamIndex = response.getFreqTrackerSettings()->getStreamIndex(); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("useReverseAPI")) { | ||||
|         settings.m_useReverseAPI = response.getFreqTrackerSettings()->getUseReverseApi() != 0; | ||||
|     } | ||||
| @ -667,6 +692,7 @@ void FreqTracker::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& r | ||||
|     response.getFreqTrackerSettings()->setRrc(settings.m_rrc ? 1 : 0); | ||||
|     response.getFreqTrackerSettings()->setRrcRolloff(settings.m_rrcRolloff); | ||||
|     response.getFreqTrackerSettings()->setSquelchGate(settings.m_squelchGate); | ||||
|     response.getFreqTrackerSettings()->setStreamIndex(settings.m_streamIndex); | ||||
|     response.getFreqTrackerSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); | ||||
| 
 | ||||
|     if (response.getFreqTrackerSettings()->getReverseApiAddress()) { | ||||
| @ -722,6 +748,9 @@ void FreqTracker::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, | ||||
|     if (channelSettingsKeys.contains("trackerType") || force) { | ||||
|         swgFreqTrackerSettings->setTrackerType((int) settings.m_trackerType); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex") || force) { | ||||
|         swgFreqTrackerSettings->setStreamIndex(settings.m_streamIndex); | ||||
|     } | ||||
| 
 | ||||
|     QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings") | ||||
|             .arg(settings.m_reverseAPIAddress) | ||||
|  | ||||
| @ -191,6 +191,8 @@ public: | ||||
|         m_magsqCount = 0; | ||||
|     } | ||||
| 
 | ||||
|     uint32_t getNumberOfDeviceStreams() const; | ||||
| 
 | ||||
|     static const QString m_channelIdURI; | ||||
|     static const QString m_channelId; | ||||
| 
 | ||||
|  | ||||
| @ -30,6 +30,7 @@ | ||||
| #include "util/simpleserializer.h" | ||||
| #include "util/db.h" | ||||
| #include "gui/basicchannelsettingsdialog.h" | ||||
| #include "gui/devicestreamselectiondialog.h" | ||||
| #include "dsp/dspengine.h" | ||||
| #include "mainwindow.h" | ||||
| #include "gui/crightclickenabler.h" | ||||
| @ -271,6 +272,20 @@ void FreqTrackerGUI::onMenuDialogCalled(const QPoint &p) | ||||
| 
 | ||||
|         applySettings(); | ||||
|     } | ||||
|     else if ((m_contextMenuType == ContextMenuStreamSettings) && (m_deviceUISet->m_deviceMIMOEngine)) | ||||
|     { | ||||
|         DeviceStreamSelectionDialog dialog(this); | ||||
|         dialog.setNumberOfStreams(m_freqTracker->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(); | ||||
| } | ||||
| @ -383,9 +398,20 @@ void FreqTrackerGUI::displaySettings() | ||||
|     ui->squelchGateText->setText(QString("%1").arg(m_settings.m_squelchGate * 10.0f, 0, 'f', 0)); | ||||
|     ui->squelchGate->setValue(m_settings.m_squelchGate); | ||||
| 
 | ||||
|     displayStreamIndex(); | ||||
| 
 | ||||
|     blockApplySettings(false); | ||||
| } | ||||
| 
 | ||||
| void FreqTrackerGUI::displayStreamIndex() | ||||
| { | ||||
|     if (m_deviceUISet->m_deviceMIMOEngine) { | ||||
|         setStreamIndicator(tr("%1").arg(m_settings.m_streamIndex)); | ||||
|     } else { | ||||
|         setStreamIndicator("S"); // single channel indicator
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void FreqTrackerGUI::leaveEvent(QEvent*) | ||||
| { | ||||
| 	m_channelMarker.setHighlighted(false); | ||||
|  | ||||
| @ -79,6 +79,7 @@ private: | ||||
|     void blockApplySettings(bool block); | ||||
| 	void applySettings(bool force = false); | ||||
| 	void displaySettings(); | ||||
|     void displayStreamIndex(); | ||||
| 
 | ||||
| 	void leaveEvent(QEvent*); | ||||
| 	void enterEvent(QEvent*); | ||||
|  | ||||
| @ -43,6 +43,7 @@ void FreqTrackerSettings::resetToDefaults() | ||||
|     m_rrc = false; | ||||
|     m_rrcRolloff = 35; | ||||
|     m_squelchGate = 5; // 50 ms
 | ||||
|     m_streamIndex = 0; | ||||
|     m_useReverseAPI = false; | ||||
|     m_reverseAPIAddress = "127.0.0.1"; | ||||
|     m_reverseAPIPort = 8888; | ||||
| @ -76,6 +77,7 @@ QByteArray FreqTrackerSettings::serialize() const | ||||
|     s.writeU32(19, m_reverseAPIDeviceIndex); | ||||
|     s.writeU32(20, m_reverseAPIChannelIndex); | ||||
|     s.writeS32(21, m_squelchGate); | ||||
|     s.writeS32(22, m_streamIndex); | ||||
| 
 | ||||
|     return s.final(); | ||||
| } | ||||
| @ -140,6 +142,7 @@ bool FreqTrackerSettings::deserialize(const QByteArray& data) | ||||
|         m_reverseAPIChannelIndex = utmp > 99 ? 99 : utmp; | ||||
|         d.readS32(21, &tmp, 5); | ||||
|         m_squelchGate = tmp < 0 ? 0 : tmp > 99 ? 99 : tmp; | ||||
|         d.readS32(22, &m_streamIndex, 0); | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| @ -48,6 +48,7 @@ struct FreqTrackerSettings | ||||
|     bool m_rrc; | ||||
|     uint32_t m_rrcRolloff; //!< in 100ths
 | ||||
|     int m_squelchGate; //!< in 10s of ms
 | ||||
|     int m_streamIndex; //!< MIMO channel. Not relevant when connected to SI (single Rx).
 | ||||
|     bool m_useReverseAPI; | ||||
|     QString m_reverseAPIAddress; | ||||
|     uint16_t m_reverseAPIPort; | ||||
|  | ||||
| @ -34,6 +34,7 @@ | ||||
| #include "dsp/dspengine.h" | ||||
| #include "dsp/devicesamplesource.h" | ||||
| #include "dsp/hbfilterchainconverter.h" | ||||
| #include "dsp/devicesamplemimo.h" | ||||
| #include "device/deviceapi.h" | ||||
| 
 | ||||
| #include "localsinkthread.h" | ||||
| @ -76,6 +77,11 @@ LocalSink::~LocalSink() | ||||
|     delete m_channelizer; | ||||
| } | ||||
| 
 | ||||
| uint32_t LocalSink::getNumberOfDeviceStreams() const | ||||
| { | ||||
|     return m_deviceAPI->getNbSourceStreams(); | ||||
| } | ||||
| 
 | ||||
| void LocalSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) | ||||
| { | ||||
|     (void) firstOfBurst; | ||||
| @ -288,6 +294,7 @@ void LocalSink::applySettings(const LocalSinkSettings& settings, bool force) | ||||
| { | ||||
|     qDebug() << "LocalSink::applySettings:" | ||||
|             << " m_localDeviceIndex: " << settings.m_localDeviceIndex | ||||
|             << " m_streamIndex: " << settings.m_streamIndex | ||||
|             << " force: " << force; | ||||
| 
 | ||||
|     QList<QString> reverseAPIKeys; | ||||
| @ -311,6 +318,21 @@ void LocalSink::applySettings(const LocalSinkSettings& 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->removeChannelSinkAPI(this, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->removeChannelSink(m_threadedChannelizer, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSink(m_threadedChannelizer, settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSinkAPI(this, settings.m_streamIndex); | ||||
|             // apply stream sample rate to itself
 | ||||
|             //applyChannelSettings(m_deviceAPI->getSampleMIMO()->getSourceSampleRate(settings.m_streamIndex), m_inputFrequencyOffset);
 | ||||
|         } | ||||
| 
 | ||||
|         reverseAPIKeys.append("streamIndex"); | ||||
|     } | ||||
| 
 | ||||
|     if ((settings.m_useReverseAPI) && (reverseAPIKeys.size() != 0)) | ||||
|     { | ||||
|         bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) || | ||||
| @ -407,6 +429,9 @@ void LocalSink::webapiUpdateChannelSettings( | ||||
|         validateFilterChainHash(settings); | ||||
|     } | ||||
| 
 | ||||
|     if (channelSettingsKeys.contains("streamIndex")) { | ||||
|         settings.m_streamIndex = response.getLocalSinkSettings()->getStreamIndex(); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("useReverseAPI")) { | ||||
|         settings.m_useReverseAPI = response.getLocalSinkSettings()->getUseReverseApi() != 0; | ||||
|     } | ||||
| @ -437,6 +462,7 @@ void LocalSink::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& res | ||||
| 
 | ||||
|     response.getLocalSinkSettings()->setLog2Decim(settings.m_log2Decim); | ||||
|     response.getLocalSinkSettings()->setFilterChainHash(settings.m_filterChainHash); | ||||
|     response.getLocalSinkSettings()->setStreamIndex(settings.m_streamIndex); | ||||
|     response.getLocalSinkSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); | ||||
| 
 | ||||
|     if (response.getLocalSinkSettings()->getReverseApiAddress()) { | ||||
| @ -477,6 +503,9 @@ void LocalSink::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, c | ||||
|     if (channelSettingsKeys.contains("filterChainHash") || force) { | ||||
|         swgLocalSinkSettings->setFilterChainHash(settings.m_filterChainHash); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex") || force) { | ||||
|         swgLocalSinkSettings->setStreamIndex(settings.m_streamIndex); | ||||
|     } | ||||
| 
 | ||||
|     QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings") | ||||
|             .arg(settings.m_reverseAPIAddress) | ||||
|  | ||||
| @ -155,6 +155,7 @@ public: | ||||
| 
 | ||||
|     void setChannelizer(unsigned int log2Decim, unsigned int filterChainHash); | ||||
|     void getLocalDevices(std::vector<uint32_t>& indexes); | ||||
|     uint32_t getNumberOfDeviceStreams() const; | ||||
| 
 | ||||
|     static const QString m_channelIdURI; | ||||
|     static const QString m_channelId; | ||||
|  | ||||
| @ -19,6 +19,7 @@ | ||||
| 
 | ||||
| #include "device/deviceuiset.h" | ||||
| #include "gui/basicchannelsettingsdialog.h" | ||||
| #include "gui/devicestreamselectiondialog.h" | ||||
| #include "dsp/hbfilterchainconverter.h" | ||||
| #include "mainwindow.h" | ||||
| 
 | ||||
| @ -194,9 +195,19 @@ void LocalSinkGUI::displaySettings() | ||||
|     blockApplySettings(true); | ||||
|     ui->decimationFactor->setCurrentIndex(m_settings.m_log2Decim); | ||||
|     applyDecimation(); | ||||
|     displayStreamIndex(); | ||||
|     blockApplySettings(false); | ||||
| } | ||||
| 
 | ||||
| void LocalSinkGUI::displayStreamIndex() | ||||
| { | ||||
|     if (m_deviceUISet->m_deviceMIMOEngine) { | ||||
|         setStreamIndicator(tr("%1").arg(m_settings.m_streamIndex)); | ||||
|     } else { | ||||
|         setStreamIndicator("S"); // single channel indicator
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void LocalSinkGUI::displayRateAndShift() | ||||
| { | ||||
|     int shift = m_shiftFrequencyFactor * m_sampleRate; | ||||
| @ -276,6 +287,20 @@ void LocalSinkGUI::onMenuDialogCalled(const QPoint &p) | ||||
| 
 | ||||
|         applySettings(); | ||||
|     } | ||||
|     else if ((m_contextMenuType == ContextMenuStreamSettings) && (m_deviceUISet->m_deviceMIMOEngine)) | ||||
|     { | ||||
|         DeviceStreamSelectionDialog dialog(this); | ||||
|         dialog.setNumberOfStreams(m_localSink->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(); | ||||
| } | ||||
|  | ||||
| @ -79,6 +79,7 @@ private: | ||||
|     void applySettings(bool force = false); | ||||
|     void applyChannelSettings(); | ||||
|     void displaySettings(); | ||||
|     void displayStreamIndex(); | ||||
|     void displayRateAndShift(); | ||||
|     void updateLocalDevices(); | ||||
| 
 | ||||
|  | ||||
| @ -36,6 +36,7 @@ void LocalSinkSettings::resetToDefaults() | ||||
|     m_log2Decim = 0; | ||||
|     m_filterChainHash = 0; | ||||
|     m_channelMarker = nullptr; | ||||
|     m_streamIndex = 0; | ||||
|     m_useReverseAPI = false; | ||||
|     m_reverseAPIAddress = "127.0.0.1"; | ||||
|     m_reverseAPIPort = 8888; | ||||
| @ -56,6 +57,7 @@ QByteArray LocalSinkSettings::serialize() const | ||||
|     s.writeU32(11, m_reverseAPIChannelIndex); | ||||
|     s.writeU32(12, m_log2Decim); | ||||
|     s.writeU32(13, m_filterChainHash); | ||||
|     s.writeS32(14, m_streamIndex); | ||||
| 
 | ||||
|     return s.final(); | ||||
| } | ||||
| @ -95,6 +97,7 @@ bool LocalSinkSettings::deserialize(const QByteArray& data) | ||||
|         d.readU32(12, &tmp, 0); | ||||
|         m_log2Decim = tmp > 6 ? 6 : tmp; | ||||
|         d.readU32(13, &m_filterChainHash, 0); | ||||
|         d.readS32(14, &m_streamIndex, 0); | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| @ -30,6 +30,7 @@ struct LocalSinkSettings | ||||
|     QString m_title; | ||||
|     uint32_t m_log2Decim; | ||||
|     uint32_t m_filterChainHash; | ||||
|     int m_streamIndex; //!< MIMO channel. Not relevant when connected to SI (single Rx).
 | ||||
|     bool m_useReverseAPI; | ||||
|     QString m_reverseAPIAddress; | ||||
|     uint16_t m_reverseAPIPort; | ||||
|  | ||||
| @ -44,6 +44,7 @@ | ||||
| #include "dsp/downchannelizer.h" | ||||
| #include "dsp/dspcommands.h" | ||||
| #include "dsp/hbfilterchainconverter.h" | ||||
| #include "dsp/devicesamplemimo.h" | ||||
| #include "device/deviceapi.h" | ||||
| 
 | ||||
| #include "remotesinkthread.h" | ||||
| @ -120,6 +121,11 @@ void RemoteSink::setNbBlocksFEC(int nbBlocksFEC) | ||||
|     m_nbBlocksFEC = nbBlocksFEC; | ||||
| } | ||||
| 
 | ||||
| uint32_t RemoteSink::getNumberOfDeviceStreams() const | ||||
| { | ||||
|     return m_deviceAPI->getNbSourceStreams(); | ||||
| } | ||||
| 
 | ||||
| void RemoteSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst) | ||||
| { | ||||
|     (void) firstOfBurst; | ||||
| @ -370,6 +376,7 @@ void RemoteSink::applySettings(const RemoteSinkSettings& settings, bool force) | ||||
|             << " m_txDelay: " << settings.m_txDelay | ||||
|             << " m_dataAddress: " << settings.m_dataAddress | ||||
|             << " m_dataPort: " << settings.m_dataPort | ||||
|             << " m_streamIndex: " << settings.m_streamIndex | ||||
|             << " force: " << force; | ||||
| 
 | ||||
|     QList<QString> reverseAPIKeys; | ||||
| @ -399,6 +406,21 @@ void RemoteSink::applySettings(const RemoteSinkSettings& settings, bool force) | ||||
|         m_dataPort = settings.m_dataPort; | ||||
|     } | ||||
| 
 | ||||
|     if (m_settings.m_streamIndex != settings.m_streamIndex) | ||||
|     { | ||||
|         if (m_deviceAPI->getSampleMIMO()) // change of stream is possible for MIMO devices only
 | ||||
|         { | ||||
|             m_deviceAPI->removeChannelSinkAPI(this, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->removeChannelSink(m_threadedChannelizer, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSink(m_threadedChannelizer, settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSinkAPI(this, settings.m_streamIndex); | ||||
|             // apply stream sample rate to itself
 | ||||
|             //applyChannelSettings(m_deviceAPI->getSampleMIMO()->getSourceSampleRate(settings.m_streamIndex), m_inputFrequencyOffset);
 | ||||
|         } | ||||
| 
 | ||||
|         reverseAPIKeys.append("streamIndex"); | ||||
|     } | ||||
| 
 | ||||
|     if ((settings.m_useReverseAPI) && (reverseAPIKeys.size() != 0)) | ||||
|     { | ||||
|         bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) || | ||||
| @ -529,6 +551,10 @@ void RemoteSink::webapiUpdateChannelSettings( | ||||
|         validateFilterChainHash(settings); | ||||
|     } | ||||
| 
 | ||||
|     if (channelSettingsKeys.contains("streamIndex")) { | ||||
|         settings.m_streamIndex = response.getRemoteSinkSettings()->getStreamIndex(); | ||||
|     } | ||||
| 
 | ||||
|     if (channelSettingsKeys.contains("useReverseAPI")) { | ||||
|         settings.m_useReverseAPI = response.getRemoteSinkSettings()->getUseReverseApi() != 0; | ||||
|     } | ||||
| @ -568,6 +594,7 @@ void RemoteSink::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& re | ||||
| 
 | ||||
|     response.getRemoteSinkSettings()->setLog2Decim(settings.m_log2Decim); | ||||
|     response.getRemoteSinkSettings()->setFilterChainHash(settings.m_filterChainHash); | ||||
|     response.getRemoteSinkSettings()->setStreamIndex(settings.m_streamIndex); | ||||
|     response.getRemoteSinkSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); | ||||
| 
 | ||||
|     if (response.getRemoteSinkSettings()->getReverseApiAddress()) { | ||||
| @ -618,6 +645,9 @@ void RemoteSink::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, | ||||
|     if (channelSettingsKeys.contains("filterChainHash") || force) { | ||||
|         swgRemoteSinkSettings->setFilterChainHash(settings.m_filterChainHash); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex") || force) { | ||||
|         swgRemoteSinkSettings->setStreamIndex(settings.m_streamIndex); | ||||
|     } | ||||
| 
 | ||||
|     QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings") | ||||
|             .arg(settings.m_reverseAPIAddress) | ||||
|  | ||||
| @ -166,6 +166,8 @@ public: | ||||
|     void setDataPort(uint16_t port) { m_dataPort = port; } | ||||
|     void setChannelizer(unsigned int log2Decim, unsigned int filterChainHash); | ||||
| 
 | ||||
|     uint32_t getNumberOfDeviceStreams() const; | ||||
| 
 | ||||
|     static const QString m_channelIdURI; | ||||
|     static const QString m_channelId; | ||||
| 
 | ||||
|  | ||||
| @ -19,6 +19,7 @@ | ||||
| 
 | ||||
| #include "device/deviceuiset.h" | ||||
| #include "gui/basicchannelsettingsdialog.h" | ||||
| #include "gui/devicestreamselectiondialog.h" | ||||
| #include "dsp/hbfilterchainconverter.h" | ||||
| #include "mainwindow.h" | ||||
| 
 | ||||
| @ -202,9 +203,19 @@ void RemoteSinkGUI::displaySettings() | ||||
|     ui->txDelay->setValue(m_settings.m_txDelay); | ||||
|     updateTxDelayTime(); | ||||
|     applyDecimation(); | ||||
|     displayStreamIndex(); | ||||
|     blockApplySettings(false); | ||||
| } | ||||
| 
 | ||||
| void RemoteSinkGUI::displayStreamIndex() | ||||
| { | ||||
|     if (m_deviceUISet->m_deviceMIMOEngine) { | ||||
|         setStreamIndicator(tr("%1").arg(m_settings.m_streamIndex)); | ||||
|     } else { | ||||
|         setStreamIndicator("S"); // single channel indicator
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void RemoteSinkGUI::displayRateAndShift() | ||||
| { | ||||
|     int shift = m_shiftFrequencyFactor * m_sampleRate; | ||||
| @ -272,6 +283,20 @@ void RemoteSinkGUI::onMenuDialogCalled(const QPoint &p) | ||||
| 
 | ||||
|         applySettings(); | ||||
|     } | ||||
|     else if ((m_contextMenuType == ContextMenuStreamSettings) && (m_deviceUISet->m_deviceMIMOEngine)) | ||||
|     { | ||||
|         DeviceStreamSelectionDialog dialog(this); | ||||
|         dialog.setNumberOfStreams(m_remoteSink->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(); | ||||
| } | ||||
|  | ||||
| @ -80,6 +80,7 @@ private: | ||||
|     void applySettings(bool force = false); | ||||
|     void applyChannelSettings(); | ||||
|     void displaySettings(); | ||||
|     void displayStreamIndex(); | ||||
|     void displayRateAndShift(); | ||||
|     void updateTxDelayTime(); | ||||
| 
 | ||||
|  | ||||
| @ -45,6 +45,7 @@ void RemoteSinkSettings::resetToDefaults() | ||||
|     m_log2Decim = 0; | ||||
|     m_filterChainHash = 0; | ||||
|     m_channelMarker = nullptr; | ||||
|     m_streamIndex = 0; | ||||
|     m_useReverseAPI = false; | ||||
|     m_reverseAPIAddress = "127.0.0.1"; | ||||
|     m_reverseAPIPort = 8888; | ||||
| @ -68,6 +69,7 @@ QByteArray RemoteSinkSettings::serialize() const | ||||
|     s.writeU32(11, m_reverseAPIChannelIndex); | ||||
|     s.writeU32(12, m_log2Decim); | ||||
|     s.writeU32(13, m_filterChainHash); | ||||
|     s.writeS32(14, m_streamIndex); | ||||
| 
 | ||||
|     return s.final(); | ||||
| } | ||||
| @ -124,6 +126,7 @@ bool RemoteSinkSettings::deserialize(const QByteArray& data) | ||||
|         d.readU32(12, &tmp, 0); | ||||
|         m_log2Decim = tmp > 6 ? 6 : tmp; | ||||
|         d.readU32(13, &m_filterChainHash, 0); | ||||
|         d.readS32(14, &m_streamIndex, 0); | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| @ -39,6 +39,7 @@ struct RemoteSinkSettings | ||||
|     QString m_title; | ||||
|     uint32_t m_log2Decim; | ||||
|     uint32_t m_filterChainHash; | ||||
|     int m_streamIndex; //!< MIMO channel. Not relevant when connected to SI (single Rx).
 | ||||
|     bool m_useReverseAPI; | ||||
|     QString m_reverseAPIAddress; | ||||
|     uint16_t m_reverseAPIPort; | ||||
|  | ||||
| @ -32,6 +32,7 @@ | ||||
| #include "dsp/downchannelizer.h" | ||||
| #include "dsp/threadedbasebandsamplesink.h" | ||||
| #include "dsp/dspcommands.h" | ||||
| #include "dsp/devicesamplemimo.h" | ||||
| #include "device/deviceapi.h" | ||||
| 
 | ||||
| #include "udpsink.h" | ||||
| @ -142,6 +143,11 @@ void UDPSink::setSpectrum(MessageQueue* messageQueue, bool enabled) | ||||
| 	messageQueue->push(cmd); | ||||
| } | ||||
| 
 | ||||
| uint32_t UDPSink::getNumberOfDeviceStreams() const | ||||
| { | ||||
|     return m_deviceAPI->getNbSourceStreams(); | ||||
| } | ||||
| 
 | ||||
| void UDPSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly) | ||||
| { | ||||
| 	Complex ci; | ||||
| @ -512,6 +518,7 @@ void UDPSink::applySettings(const UDPSinkSettings& settings, bool force) | ||||
|             << " m_udpAddressStr: " << settings.m_udpAddress | ||||
|             << " m_udpPort: " << settings.m_udpPort | ||||
|             << " m_audioPort: " << settings.m_audioPort | ||||
|             << " m_streamIndex: " << settings.m_streamIndex | ||||
|             << " m_useReverseAPI: " << settings.m_useReverseAPI | ||||
|             << " m_reverseAPIAddress: " << settings.m_reverseAPIAddress | ||||
|             << " m_reverseAPIPort: " << settings.m_reverseAPIPort | ||||
| @ -682,6 +689,21 @@ void UDPSink::applySettings(const UDPSinkSettings& settings, bool force) | ||||
| 
 | ||||
|     m_settingsMutex.unlock(); | ||||
| 
 | ||||
|     if (m_settings.m_streamIndex != settings.m_streamIndex) | ||||
|     { | ||||
|         if (m_deviceAPI->getSampleMIMO()) // change of stream is possible for MIMO devices only
 | ||||
|         { | ||||
|             m_deviceAPI->removeChannelSinkAPI(this, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->removeChannelSink(m_threadedChannelizer, m_settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSink(m_threadedChannelizer, settings.m_streamIndex); | ||||
|             m_deviceAPI->addChannelSinkAPI(this, settings.m_streamIndex); | ||||
|             // apply stream sample rate to itself
 | ||||
|             applyChannelSettings(m_deviceAPI->getSampleMIMO()->getSourceSampleRate(settings.m_streamIndex), m_inputFrequencyOffset); | ||||
|         } | ||||
| 
 | ||||
|         reverseAPIKeys.append("streamIndex"); | ||||
|     } | ||||
| 
 | ||||
|     if (settings.m_useReverseAPI) | ||||
|     { | ||||
|         bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) || | ||||
| @ -823,6 +845,9 @@ void UDPSink::webapiUpdateChannelSettings( | ||||
|     if (channelSettingsKeys.contains("title")) { | ||||
|         settings.m_title = *response.getUdpSinkSettings()->getTitle(); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex")) { | ||||
|         settings.m_streamIndex = response.getUdpSinkSettings()->getStreamIndex(); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("useReverseAPI")) { | ||||
|         settings.m_useReverseAPI = response.getUdpSinkSettings()->getUseReverseApi() != 0; | ||||
|     } | ||||
| @ -884,6 +909,7 @@ void UDPSink::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& respo | ||||
|         response.getUdpSinkSettings()->setTitle(new QString(settings.m_title)); | ||||
|     } | ||||
| 
 | ||||
|     response.getUdpSinkSettings()->setStreamIndex(settings.m_streamIndex); | ||||
|     response.getUdpSinkSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); | ||||
| 
 | ||||
|     if (response.getUdpSinkSettings()->getReverseApiAddress()) { | ||||
| @ -974,6 +1000,9 @@ void UDPSink::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, con | ||||
|     if (channelSettingsKeys.contains("title") || force) { | ||||
|         swgUDPSinkSettings->setTitle(new QString(settings.m_title)); | ||||
|     } | ||||
|     if (channelSettingsKeys.contains("streamIndex") || force) { | ||||
|         swgUDPSinkSettings->setStreamIndex(settings.m_streamIndex); | ||||
|     } | ||||
| 
 | ||||
|     QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings") | ||||
|             .arg(settings.m_reverseAPIAddress) | ||||
|  | ||||
| @ -151,6 +151,8 @@ public: | ||||
|             const QStringList& channelSettingsKeys, | ||||
|             SWGSDRangel::SWGChannelSettings& response); | ||||
| 
 | ||||
|     uint32_t getNumberOfDeviceStreams() const; | ||||
| 
 | ||||
|     static const QString m_channelIdURI; | ||||
|     static const QString m_channelId; | ||||
| 	static const int udpBlockSize = 512; // UDP block size in number of bytes
 | ||||
|  | ||||
| @ -23,6 +23,7 @@ | ||||
| #include "util/simpleserializer.h" | ||||
| #include "util/db.h" | ||||
| #include "gui/basicchannelsettingsdialog.h" | ||||
| #include "gui/devicestreamselectiondialog.h" | ||||
| #include "ui_udpsinkgui.h" | ||||
| #include "mainwindow.h" | ||||
| 
 | ||||
| @ -284,11 +285,22 @@ void UDPSinkGUI::displaySettings() | ||||
|     ui->applyBtn->setEnabled(false); | ||||
|     ui->applyBtn->setStyleSheet("QPushButton { background:rgb(79,79,79); }"); | ||||
| 
 | ||||
|     displayStreamIndex(); | ||||
| 
 | ||||
|     blockApplySettings(false); | ||||
| 
 | ||||
|     ui->glSpectrum->setSampleRate(m_settings.m_outputSampleRate); | ||||
| } | ||||
| 
 | ||||
| void UDPSinkGUI::displayStreamIndex() | ||||
| { | ||||
|     if (m_deviceUISet->m_deviceMIMOEngine) { | ||||
|         setStreamIndicator(tr("%1").arg(m_settings.m_streamIndex)); | ||||
|     } else { | ||||
|         setStreamIndicator("S"); // single channel indicator
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void UDPSinkGUI::setSampleFormatIndex(const UDPSinkSettings::SampleFormat& sampleFormat) | ||||
| { | ||||
|     switch(sampleFormat) | ||||
| @ -640,6 +652,20 @@ void UDPSinkGUI::onMenuDialogCalled(const QPoint &p) | ||||
| 
 | ||||
|         applySettingsImmediate(); | ||||
|     } | ||||
|     else if ((m_contextMenuType == ContextMenuStreamSettings) && (m_deviceUISet->m_deviceMIMOEngine)) | ||||
|     { | ||||
|         DeviceStreamSelectionDialog dialog(this); | ||||
|         dialog.setNumberOfStreams(m_udpSink->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(); | ||||
| } | ||||
|  | ||||
| @ -86,6 +86,7 @@ private: | ||||
| 	void applySettings(bool force = false); | ||||
| 	void applySettingsImmediate(bool force = false); | ||||
| 	void displaySettings(); | ||||
|     void displayStreamIndex(); | ||||
| 	void setSampleFormat(int index); | ||||
| 	void setSampleFormatIndex(const UDPSinkSettings::SampleFormat& sampleFormat); | ||||
| 
 | ||||
|  | ||||
| @ -45,6 +45,7 @@ void UDPSinkSettings::resetToDefaults() | ||||
|     m_audioActive = false; | ||||
|     m_audioStereo = false; | ||||
|     m_volume = 20; | ||||
|     m_streamIndex = 0; | ||||
|     m_udpAddress = "127.0.0.1"; | ||||
|     m_udpPort = 9998; | ||||
|     m_audioPort = 9997; | ||||
| @ -91,6 +92,7 @@ QByteArray UDPSinkSettings::serialize() const | ||||
|     s.writeU32(25, m_reverseAPIPort); | ||||
|     s.writeU32(26, m_reverseAPIDeviceIndex); | ||||
|     s.writeU32(27, m_reverseAPIChannelIndex); | ||||
|     s.writeS32(28, m_streamIndex); | ||||
| 
 | ||||
|     return s.final(); | ||||
| 
 | ||||
| @ -180,6 +182,7 @@ bool UDPSinkSettings::deserialize(const QByteArray& data) | ||||
|         m_reverseAPIDeviceIndex = u32tmp > 99 ? 99 : u32tmp; | ||||
|         d.readU32(27, &u32tmp, 0); | ||||
|         m_reverseAPIChannelIndex = u32tmp > 99 ? 99 : u32tmp; | ||||
|         d.readS32(28, &m_streamIndex, 0); | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| @ -63,6 +63,7 @@ struct UDPSinkSettings | ||||
| 
 | ||||
|     QString m_title; | ||||
| 
 | ||||
|     int m_streamIndex; //!< MIMO channel. Not relevant when connected to SI (single Rx).
 | ||||
|     bool m_useReverseAPI; | ||||
|     QString m_reverseAPIAddress; | ||||
|     uint16_t m_reverseAPIPort; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user