Skip to content

Commit

Permalink
Add setting to have the volume of NVDA sounds follow the voice volume.
Browse files Browse the repository at this point in the history
  • Loading branch information
jcsteh committed May 2, 2023
1 parent e77bde9 commit 24a90e9
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 1 deletion.
1 change: 1 addition & 0 deletions source/config/configSpec.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
[audio]
audioDuckingMode = integer(default=0)
wasapi = boolean(default=true)
soundVolumeFollowsVoice = boolean(default=false)
# Braille settings
[braille]
Expand Down
16 changes: 15 additions & 1 deletion source/gui/settingsDialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3032,6 +3032,18 @@ def __init__(self, parent):
)
self.wasapiCheckBox.defaultValue = self._getDefaultValue(
["audio", "wasapi"])
# Translators: This is the label for a checkbox control in the
# Advanced settings panel.
label = _("Volume of NVDA sounds follows voice volume (requires WASAPI)")
self.soundVolFollowCheckBox: wx.CheckBox = audioGroup.addItem(
wx.CheckBox(audioBox, label=label)
)
self.bindHelpEvent("SoundVolumeFollowsVoice", self.soundVolFollowCheckBox)
self.soundVolFollowCheckBox.SetValue(
config.conf["audio"]["soundVolumeFollowsVoice"]
)
self.soundVolFollowCheckBox.defaultValue = self._getDefaultValue(
["audio", "soundVolumeFollowsVoice"])

# Translators: This is the label for a group of advanced options in the
# Advanced settings panel
Expand Down Expand Up @@ -3121,6 +3133,7 @@ def haveConfigDefaultsBeenRestored(self):
and self.caretMoveTimeoutSpinControl.GetValue() == self.caretMoveTimeoutSpinControl.defaultValue
and self.reportTransparentColorCheckBox.GetValue() == self.reportTransparentColorCheckBox.defaultValue
and self.wasapiCheckBox.GetValue() == self.wasapiCheckBox.defaultValue
and self.soundVolFollowCheckBox.GetValue() == self.soundVolFollowCheckBox.defaultValue
and set(self.logCategoriesList.CheckedItems) == set(self.logCategoriesList.defaultCheckedItems)
and self.playErrorSoundCombo.GetSelection() == self.playErrorSoundCombo.defaultValue
and True # reduce noise in diff when the list is extended.
Expand All @@ -3147,6 +3160,7 @@ def restoreToDefaults(self):
self.caretMoveTimeoutSpinControl.SetValue(self.caretMoveTimeoutSpinControl.defaultValue)
self.reportTransparentColorCheckBox.SetValue(self.reportTransparentColorCheckBox.defaultValue)
self.wasapiCheckBox.SetValue(self.wasapiCheckBox.defaultValue)
self.soundVolFollowCheckBox.SetValue(self.soundVolFollowCheckBox.defaultValue)
self.logCategoriesList.CheckedItems = self.logCategoriesList.defaultCheckedItems
self.playErrorSoundCombo.SetSelection(self.playErrorSoundCombo.defaultValue)
self._defaultsRestored = True
Expand Down Expand Up @@ -3177,7 +3191,7 @@ def onSave(self):
config.conf["documentFormatting"]["reportTransparentColor"] = (
self.reportTransparentColorCheckBox.IsChecked()
)
config.conf["audio"]["wasapi"] = self.wasapiCheckBox.IsChecked()
config.conf["audio"]["soundVolumeFollowsVoice"] = self.soundVolFollowCheckBox.IsChecked()
config.conf["annotations"]["reportDetails"] = self.annotationsDetailsCheckBox.IsChecked()
config.conf["annotations"]["reportAriaDescription"] = self.ariaDescCheckBox.IsChecked()
config.conf["braille"]["enableHidBrailleSupport"] = self.supportHidBrailleCombo.GetSelection()
Expand Down
14 changes: 14 additions & 0 deletions source/nvwave.py
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,7 @@ def __init__(
import audioDucking
if audioDucking.isAudioDuckingSupported():
self._audioDucker = audioDucking.AudioDucker()
self._session = session
self._player = NVDAHelper.localLib.wasPlay_create(
self._deviceNameToId(outputDevice),
format,
Expand Down Expand Up @@ -857,6 +858,7 @@ def open(self):
WavePlayer.audioDeviceError_static = True
raise
WasapiWavePlayer.audioDeviceError_static = False
self._sessionVolumeFollow()

def close(self):
"""For WASAPI, this just stops playback.
Expand Down Expand Up @@ -913,6 +915,7 @@ def stop(self):
self._audioDucker.disable()
NVDAHelper.localLib.wasPlay_stop(self._player)
self._doneCallbacks = {}
self._sessionVolumeFollow()

def pause(self, switch: bool):
"""Pause or unpause playback.
Expand All @@ -935,6 +938,17 @@ def setSessionVolume(self, level: float):
"""
NVDAHelper.localLib.wasPlay_setSessionVolume(self._player, c_float(level))

def _sessionVolumeFollow(self):
if (
self._session is not soundsSession
or not config.conf["audio"]["soundVolumeFollowsVoice"]
):
return
import synthDriverHandler
synth = synthDriverHandler.getSynth()
if synth and synth.isSupported("volume"):
self.setSessionVolume(synth.volume / 100)

@staticmethod
def _getDevices():
rawDevs = BSTR()
Expand Down
7 changes: 7 additions & 0 deletions user_docs/en/userGuide.t2t
Original file line number Diff line number Diff line change
Expand Up @@ -2299,6 +2299,13 @@ WASAPI is a more modern audio framework which may improve the responsiveness, pe
This option is enabled by default.
After changing this option, you will need to restart NVDA for the change to take effect.

==== Volume of NVDA sounds follows voice volume ====[SoundVolumeFollowsVoice]
When this option is enabled, the volume of NVDA sounds and beeps will follow the volume setting of the voice you are using.
If you decrease the volume of the voice, the volume of sounds will decrease.
Similarly, if you increase the volume of the voice, the volume of sounds will increase.
This option only takes effect when Use WASAPI for audio output is enabled.
This option is disabled by default.

==== Debug logging categories ====[AdvancedSettingsDebugLoggingCategories]
The checkboxes in this list allow you to enable specific categories of debug messages in NVDA's log.
Logging these messages can result in decreased performance and large log files.
Expand Down

0 comments on commit 24a90e9

Please sign in to comment.