mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-31 13:00:26 -04:00 
			
		
		
		
	Audio output: Make settings assignments atomic. Part of #1329
This commit is contained in:
		
							parent
							
								
									96d0bef47e
								
							
						
					
					
						commit
						ae3864a56b
					
				| @ -63,7 +63,7 @@ void AudioOutput::destroy() | |||||||
| 
 | 
 | ||||||
| void AudioOutput::init() | void AudioOutput::init() | ||||||
| { | { | ||||||
|     applySettings(m_settings, true); |     applySettings(m_settings, QList<QString>(), true); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool AudioOutput::start() | bool AudioOutput::start() | ||||||
| @ -139,12 +139,12 @@ bool AudioOutput::deserialize(const QByteArray& data) | |||||||
|         success = false; |         success = false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     MsgConfigureAudioOutput* message = MsgConfigureAudioOutput::create(m_settings, true); |     MsgConfigureAudioOutput* message = MsgConfigureAudioOutput::create(m_settings, QList<QString>(), true); | ||||||
|     m_inputMessageQueue.push(message); |     m_inputMessageQueue.push(message); | ||||||
| 
 | 
 | ||||||
|     if (m_guiMessageQueue) |     if (m_guiMessageQueue) | ||||||
|     { |     { | ||||||
|         MsgConfigureAudioOutput* messageToGUI = MsgConfigureAudioOutput::create(m_settings, true); |         MsgConfigureAudioOutput* messageToGUI = MsgConfigureAudioOutput::create(m_settings, QList<QString>(), true); | ||||||
|         m_guiMessageQueue->push(messageToGUI); |         m_guiMessageQueue->push(messageToGUI); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -172,7 +172,7 @@ bool AudioOutput::handleMessage(const Message& message) | |||||||
|     { |     { | ||||||
|         qDebug() << "AudioOutput::handleMessage: MsgConfigureAudioOutput"; |         qDebug() << "AudioOutput::handleMessage: MsgConfigureAudioOutput"; | ||||||
|         MsgConfigureAudioOutput& conf = (MsgConfigureAudioOutput&) message; |         MsgConfigureAudioOutput& conf = (MsgConfigureAudioOutput&) message; | ||||||
|         applySettings(conf.getSettings(), conf.getForce()); |         applySettings(conf.getSettings(), conf.getSettingsKeys(), conf.getForce()); | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|     else if (MsgStartStop::match(message)) |     else if (MsgStartStop::match(message)) | ||||||
| @ -203,14 +203,13 @@ bool AudioOutput::handleMessage(const Message& message) | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AudioOutput::applySettings(const AudioOutputSettings& settings, bool force) | void AudioOutput::applySettings(const AudioOutputSettings& settings, const QList<QString>& settingsKeys, bool force) | ||||||
| { | { | ||||||
|  |     qDebug() << "AudioOutput::applySettings: force:" << force << settings.getDebugString(settingsKeys, force); | ||||||
|     bool forwardChange = false; |     bool forwardChange = false; | ||||||
|     QList<QString> reverseAPIKeys; |  | ||||||
| 
 | 
 | ||||||
|     if ((m_settings.m_deviceName != settings.m_deviceName) || force) |     if (settingsKeys.contains("deviceName") || force) | ||||||
|     { |     { | ||||||
|         reverseAPIKeys.append("deviceName"); |  | ||||||
|         AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager(); |         AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager(); | ||||||
|         m_audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_deviceName); |         m_audioDeviceIndex = audioDeviceManager->getOutputDeviceIndex(settings.m_deviceName); | ||||||
|         //qDebug("AMDemod::applySettings: audioDeviceName: %s audioDeviceIndex: %d", qPrintable(settings.m_audioDeviceName), audioDeviceIndex);
 |         //qDebug("AMDemod::applySettings: audioDeviceName: %s audioDeviceIndex: %d", qPrintable(settings.m_audioDeviceName), audioDeviceIndex);
 | ||||||
| @ -220,16 +219,14 @@ void AudioOutput::applySettings(const AudioOutputSettings& settings, bool force) | |||||||
|         forwardChange = true; |         forwardChange = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if ((m_settings.m_volume != settings.m_volume) || force) |     if (settingsKeys.contains("volume") || force) | ||||||
|     { |     { | ||||||
|         reverseAPIKeys.append("volume"); |  | ||||||
|         m_audioOutputDevice.setVolume(settings.m_volume); |         m_audioOutputDevice.setVolume(settings.m_volume); | ||||||
|         qDebug() << "AudioOutput::applySettings: set volume to " << settings.m_volume; |         qDebug() << "AudioOutput::applySettings: set volume to " << settings.m_volume; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if ((m_settings.m_iqMapping != settings.m_iqMapping) || force) |     if (settingsKeys.contains("iqMapping") || force) | ||||||
|     { |     { | ||||||
|         reverseAPIKeys.append("iqMapping"); |  | ||||||
|         forwardChange = true; |         forwardChange = true; | ||||||
| 
 | 
 | ||||||
|         if (m_running) { |         if (m_running) { | ||||||
| @ -237,16 +234,20 @@ void AudioOutput::applySettings(const AudioOutputSettings& settings, bool force) | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (settings.m_useReverseAPI) |     if (settingsKeys.contains("useReverseAPI")) | ||||||
|     { |     { | ||||||
|         bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) || |         bool fullUpdate = (settingsKeys.contains("useReverseAPI") && settings.m_useReverseAPI) || | ||||||
|                 (m_settings.m_reverseAPIAddress != settings.m_reverseAPIAddress) || |             settingsKeys.contains("reverseAPIAddress") || | ||||||
|                 (m_settings.m_reverseAPIPort != settings.m_reverseAPIPort) || |             settingsKeys.contains("reverseAPIPort") || | ||||||
|                 (m_settings.m_reverseAPIDeviceIndex != settings.m_reverseAPIDeviceIndex); |             settingsKeys.contains("reverseAPIDeviceIndex"); | ||||||
|         webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force); |         webapiReverseSendSettings(settingsKeys, settings, fullUpdate || force); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     m_settings = settings; |     if (force) { | ||||||
|  |         m_settings = settings; | ||||||
|  |     } else { | ||||||
|  |         m_settings.applySettings(settingsKeys, settings); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     if (forwardChange) |     if (forwardChange) | ||||||
|     { |     { | ||||||
| @ -310,12 +311,12 @@ int AudioOutput::webapiSettingsPutPatch( | |||||||
|     AudioOutputSettings settings = m_settings; |     AudioOutputSettings settings = m_settings; | ||||||
|     webapiUpdateDeviceSettings(settings, deviceSettingsKeys, response); |     webapiUpdateDeviceSettings(settings, deviceSettingsKeys, response); | ||||||
| 
 | 
 | ||||||
|     MsgConfigureAudioOutput *msg = MsgConfigureAudioOutput::create(settings, force); |     MsgConfigureAudioOutput *msg = MsgConfigureAudioOutput::create(settings, deviceSettingsKeys, force); | ||||||
|     m_inputMessageQueue.push(msg); |     m_inputMessageQueue.push(msg); | ||||||
| 
 | 
 | ||||||
|     if (m_guiMessageQueue) // forward to GUI if any
 |     if (m_guiMessageQueue) // forward to GUI if any
 | ||||||
|     { |     { | ||||||
|         MsgConfigureAudioOutput *msgToGUI = MsgConfigureAudioOutput::create(settings, force); |         MsgConfigureAudioOutput *msgToGUI = MsgConfigureAudioOutput::create(settings, deviceSettingsKeys, force); | ||||||
|         m_guiMessageQueue->push(msgToGUI); |         m_guiMessageQueue->push(msgToGUI); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -369,7 +370,7 @@ void AudioOutput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& res | |||||||
|     response.getAudioOutputSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex); |     response.getAudioOutputSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AudioOutput::webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const AudioOutputSettings& settings, bool force) | void AudioOutput::webapiReverseSendSettings(const QList<QString>& deviceSettingsKeys, const AudioOutputSettings& settings, bool force) | ||||||
| { | { | ||||||
|     SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings(); |     SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings(); | ||||||
|     swgDeviceSettings->setDirection(1); // single Tx
 |     swgDeviceSettings->setDirection(1); // single Tx
 | ||||||
|  | |||||||
| @ -39,20 +39,22 @@ public: | |||||||
| 
 | 
 | ||||||
| 	public: | 	public: | ||||||
| 		const AudioOutputSettings& getSettings() const { return m_settings; } | 		const AudioOutputSettings& getSettings() const { return m_settings; } | ||||||
|  |         const QList<QString>& getSettingsKeys() const { return m_settingsKeys; } | ||||||
| 		bool getForce() const { return m_force; } | 		bool getForce() const { return m_force; } | ||||||
| 
 | 
 | ||||||
| 		static MsgConfigureAudioOutput* create(const AudioOutputSettings& settings, bool force) | 		static MsgConfigureAudioOutput* create(const AudioOutputSettings& settings, const QList<QString>& settingsKeys, bool force) { | ||||||
| 		{ | 			return new MsgConfigureAudioOutput(settings, settingsKeys, force); | ||||||
| 			return new MsgConfigureAudioOutput(settings, force); |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	private: | 	private: | ||||||
| 		AudioOutputSettings m_settings; | 		AudioOutputSettings m_settings; | ||||||
|  |         QList<QString> m_settingsKeys; | ||||||
| 		bool m_force; | 		bool m_force; | ||||||
| 
 | 
 | ||||||
| 		MsgConfigureAudioOutput(const AudioOutputSettings& settings, bool force) : | 		MsgConfigureAudioOutput(const AudioOutputSettings& settings, const QList<QString>& settingsKeys, bool force) : | ||||||
| 			Message(), | 			Message(), | ||||||
| 			m_settings(settings), | 			m_settings(settings), | ||||||
|  |             m_settingsKeys(settingsKeys), | ||||||
| 			m_force(force) | 			m_force(force) | ||||||
| 		{ } | 		{ } | ||||||
| 	}; | 	}; | ||||||
| @ -140,9 +142,8 @@ private: | |||||||
|     QNetworkAccessManager *m_networkManager; |     QNetworkAccessManager *m_networkManager; | ||||||
|     QNetworkRequest m_networkRequest; |     QNetworkRequest m_networkRequest; | ||||||
| 
 | 
 | ||||||
|     void applySettings(const AudioOutputSettings& settings, bool force); |     void applySettings(const AudioOutputSettings& settings, const QList<QString>& settingsKeys, bool force); | ||||||
| 
 |     void webapiReverseSendSettings(const QList<QString>& deviceSettingsKeys, const AudioOutputSettings& settings, bool force); | ||||||
|     void webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const AudioOutputSettings& settings, bool force); |  | ||||||
|     void webapiReverseSendStartStop(bool start); |     void webapiReverseSendStartStop(bool start); | ||||||
| 
 | 
 | ||||||
| private slots: | private slots: | ||||||
|  | |||||||
| @ -78,6 +78,7 @@ void AudioOutputGui::resetToDefaults() | |||||||
| { | { | ||||||
|     m_settings.resetToDefaults(); |     m_settings.resetToDefaults(); | ||||||
|     displaySettings(); |     displaySettings(); | ||||||
|  |     m_forceSettings = true; | ||||||
|     sendSettings(); |     sendSettings(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -113,7 +114,13 @@ bool AudioOutputGui::handleMessage(const Message& message) | |||||||
|     if (AudioOutput::MsgConfigureAudioOutput::match(message)) |     if (AudioOutput::MsgConfigureAudioOutput::match(message)) | ||||||
|     { |     { | ||||||
|         const AudioOutput::MsgConfigureAudioOutput& cfg = (AudioOutput::MsgConfigureAudioOutput&) message; |         const AudioOutput::MsgConfigureAudioOutput& cfg = (AudioOutput::MsgConfigureAudioOutput&) message; | ||||||
|         m_settings = cfg.getSettings(); | 
 | ||||||
|  |         if (cfg.getForce()) { | ||||||
|  |             m_settings = cfg.getSettings(); | ||||||
|  |         } else { | ||||||
|  |             m_settings.applySettings(cfg.getSettingsKeys(), cfg.getSettings()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         blockApplySettings(true); |         blockApplySettings(true); | ||||||
|         displaySettings(); |         displaySettings(); | ||||||
|         blockApplySettings(false); |         blockApplySettings(false); | ||||||
| @ -185,6 +192,7 @@ void AudioOutputGui::on_deviceSelect_clicked() | |||||||
|     if (audioSelect.m_selected) |     if (audioSelect.m_selected) | ||||||
|     { |     { | ||||||
|         m_settings.m_deviceName = audioSelect.m_audioDeviceName; |         m_settings.m_deviceName = audioSelect.m_audioDeviceName; | ||||||
|  |         m_settingsKeys.append("deviceName"); | ||||||
|         ui->deviceLabel->setText(m_settings.m_deviceName); |         ui->deviceLabel->setText(m_settings.m_deviceName); | ||||||
|         sendSettings(); |         sendSettings(); | ||||||
|     } |     } | ||||||
| @ -194,12 +202,14 @@ void AudioOutputGui::on_volume_valueChanged(int value) | |||||||
| { | { | ||||||
|     m_settings.m_volume = value/10.0f; |     m_settings.m_volume = value/10.0f; | ||||||
|     ui->volumeText->setText(QString("%1").arg(m_settings.m_volume, 3, 'f', 1)); |     ui->volumeText->setText(QString("%1").arg(m_settings.m_volume, 3, 'f', 1)); | ||||||
|  |     m_settingsKeys.append("volume"); | ||||||
|     sendSettings(); |     sendSettings(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AudioOutputGui::on_channels_currentIndexChanged(int index) | void AudioOutputGui::on_channels_currentIndexChanged(int index) | ||||||
| { | { | ||||||
|     m_settings.m_iqMapping = (AudioOutputSettings::IQMapping) index; |     m_settings.m_iqMapping = (AudioOutputSettings::IQMapping) index; | ||||||
|  |     m_settingsKeys.append("iqMapping"); | ||||||
|     updateSampleRateAndFrequency(); |     updateSampleRateAndFrequency(); | ||||||
|     sendSettings(); |     sendSettings(); | ||||||
| } | } | ||||||
| @ -215,17 +225,19 @@ void AudioOutputGui::on_startStop_toggled(bool checked) | |||||||
| 
 | 
 | ||||||
| void AudioOutputGui::sendSettings() | void AudioOutputGui::sendSettings() | ||||||
| { | { | ||||||
|     if(!m_updateTimer.isActive()) |     if (!m_updateTimer.isActive()) { | ||||||
|         m_updateTimer.start(100); |         m_updateTimer.start(100); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AudioOutputGui::updateHardware() | void AudioOutputGui::updateHardware() | ||||||
| { | { | ||||||
|     if (m_doApplySettings) |     if (m_doApplySettings) | ||||||
|     { |     { | ||||||
|         AudioOutput::MsgConfigureAudioOutput* message = AudioOutput::MsgConfigureAudioOutput::create(m_settings, m_forceSettings); |         AudioOutput::MsgConfigureAudioOutput* message = AudioOutput::MsgConfigureAudioOutput::create(m_settings, m_settingsKeys, m_forceSettings); | ||||||
|         m_audioOutput->getInputMessageQueue()->push(message); |         m_audioOutput->getInputMessageQueue()->push(message); | ||||||
|         m_forceSettings = false; |         m_forceSettings = false; | ||||||
|  |         m_settingsKeys.clear(); | ||||||
|         m_updateTimer.stop(); |         m_updateTimer.stop(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -247,6 +259,10 @@ void AudioOutputGui::openDeviceSettingsDialog(const QPoint& p) | |||||||
|         m_settings.m_reverseAPIAddress = dialog.getReverseAPIAddress(); |         m_settings.m_reverseAPIAddress = dialog.getReverseAPIAddress(); | ||||||
|         m_settings.m_reverseAPIPort = dialog.getReverseAPIPort(); |         m_settings.m_reverseAPIPort = dialog.getReverseAPIPort(); | ||||||
|         m_settings.m_reverseAPIDeviceIndex = dialog.getReverseAPIDeviceIndex(); |         m_settings.m_reverseAPIDeviceIndex = dialog.getReverseAPIDeviceIndex(); | ||||||
|  |         m_settingsKeys.append("useReverseAPI"); | ||||||
|  |         m_settingsKeys.append("reverseAPIAddress"); | ||||||
|  |         m_settingsKeys.append("reverseAPIPort"); | ||||||
|  |         m_settingsKeys.append("reverseAPIDeviceIndex"); | ||||||
| 
 | 
 | ||||||
|         sendSettings(); |         sendSettings(); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -56,6 +56,7 @@ private: | |||||||
|     bool m_doApplySettings; |     bool m_doApplySettings; | ||||||
|     bool m_forceSettings; |     bool m_forceSettings; | ||||||
|     AudioOutputSettings m_settings; |     AudioOutputSettings m_settings; | ||||||
|  |     QList<QString> m_settingsKeys; | ||||||
|     QTimer m_updateTimer; |     QTimer m_updateTimer; | ||||||
|     int m_sampleRate; |     int m_sampleRate; | ||||||
|     qint64 m_centerFrequency; |     qint64 m_centerFrequency; | ||||||
|  | |||||||
| @ -91,3 +91,57 @@ bool AudioOutputSettings::deserialize(const QByteArray& data) | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void AudioOutputSettings::applySettings(const QStringList& settingsKeys, const AudioOutputSettings& settings) | ||||||
|  | { | ||||||
|  |     if (settingsKeys.contains("deviceName")) { | ||||||
|  |         m_deviceName = settings.m_deviceName; | ||||||
|  |     } | ||||||
|  |     if (settingsKeys.contains("volume")) { | ||||||
|  |         m_volume = settings.m_volume; | ||||||
|  |     } | ||||||
|  |     if (settingsKeys.contains("iqMapping")) { | ||||||
|  |         m_iqMapping = settings.m_iqMapping; | ||||||
|  |     } | ||||||
|  |     if (settingsKeys.contains("useReverseAPI")) { | ||||||
|  |         m_useReverseAPI = settings.m_useReverseAPI; | ||||||
|  |     } | ||||||
|  |     if (settingsKeys.contains("reverseAPIAddress")) { | ||||||
|  |         m_reverseAPIAddress = settings.m_reverseAPIAddress; | ||||||
|  |     } | ||||||
|  |     if (settingsKeys.contains("reverseAPIPort")) { | ||||||
|  |         m_reverseAPIPort = settings.m_reverseAPIPort; | ||||||
|  |     } | ||||||
|  |     if (settingsKeys.contains("reverseAPIDeviceIndex")) { | ||||||
|  |         m_reverseAPIDeviceIndex = settings.m_reverseAPIDeviceIndex; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | QString AudioOutputSettings::getDebugString(const QStringList& settingsKeys, bool force) const | ||||||
|  | { | ||||||
|  |     std::ostringstream ostr; | ||||||
|  | 
 | ||||||
|  |     if (settingsKeys.contains("deviceName") || force) { | ||||||
|  |         ostr << " m_deviceName: " << m_deviceName.toStdString(); | ||||||
|  |     } | ||||||
|  |     if (settingsKeys.contains("volume") || force) { | ||||||
|  |         ostr << " m_volume: " << m_volume; | ||||||
|  |     } | ||||||
|  |     if (settingsKeys.contains("iqMapping") || force) { | ||||||
|  |         ostr << " m_iqMapping: " << m_iqMapping; | ||||||
|  |     } | ||||||
|  |     if (settingsKeys.contains("useReverseAPI") || force) { | ||||||
|  |         ostr << " m_useReverseAPI: " << m_useReverseAPI; | ||||||
|  |     } | ||||||
|  |     if (settingsKeys.contains("reverseAPIAddress") || force) { | ||||||
|  |         ostr << " m_reverseAPIAddress: " << m_reverseAPIAddress.toStdString(); | ||||||
|  |     } | ||||||
|  |     if (settingsKeys.contains("reverseAPIPort") || force) { | ||||||
|  |         ostr << " m_reverseAPIPort: " << m_reverseAPIPort; | ||||||
|  |     } | ||||||
|  |     if (settingsKeys.contains("reverseAPIDeviceIndex") || force) { | ||||||
|  |         ostr << " m_reverseAPIDeviceIndex: " << m_reverseAPIDeviceIndex; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return QString(ostr.str().c_str()); | ||||||
|  | } | ||||||
|  | |||||||
| @ -39,6 +39,8 @@ struct AudioOutputSettings { | |||||||
|     void resetToDefaults(); |     void resetToDefaults(); | ||||||
|     QByteArray serialize() const; |     QByteArray serialize() const; | ||||||
|     bool deserialize(const QByteArray& data); |     bool deserialize(const QByteArray& data); | ||||||
|  |     void applySettings(const QStringList& settingsKeys, const AudioOutputSettings& settings); | ||||||
|  |     QString getDebugString(const QStringList& settingsKeys, bool force=false) const; | ||||||
| 
 | 
 | ||||||
|     // Append realm to device names, because there may be multiple devices with the same name on Windows
 |     // Append realm to device names, because there may be multiple devices with the same name on Windows
 | ||||||
|     static QString getFullDeviceName(const QAudioDeviceInfo &deviceInfo) |     static QString getFullDeviceName(const QAudioDeviceInfo &deviceInfo) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user