Skip to content

Commit

Permalink
Add sound split disabled mode (#16331)
Browse files Browse the repository at this point in the history
Closes #16287

Summary of the issue:
Disabling sound split still could touch channel volumes.

Description of development approach
1. If sound split mode is disabled at startup, we're not touching any volumes.
2. If user toggles to disabled mode, then first we set mode to NVDA_BOTH_APPS_BOTH to effectively restore the volumes, then set sound pslit state to off.
  • Loading branch information
mltony committed Apr 8, 2024
1 parent a9f4024 commit 25f562f
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 14 deletions.
52 changes: 39 additions & 13 deletions source/audio/soundSplit.py
Expand Up @@ -23,18 +23,25 @@
@unique
class SoundSplitState(DisplayStringIntEnum):
OFF = 0
NVDA_LEFT_APPS_RIGHT = 1
NVDA_LEFT_APPS_BOTH = 2
NVDA_RIGHT_APPS_LEFT = 3
NVDA_RIGHT_APPS_BOTH = 4
NVDA_BOTH_APPS_LEFT = 5
NVDA_BOTH_APPS_RIGHT = 6
NVDA_BOTH_APPS_BOTH = 1
NVDA_LEFT_APPS_RIGHT = 2
NVDA_LEFT_APPS_BOTH = 3
NVDA_RIGHT_APPS_LEFT = 4
NVDA_RIGHT_APPS_BOTH = 5
NVDA_BOTH_APPS_LEFT = 6
NVDA_BOTH_APPS_RIGHT = 7


@property
def _displayStringLabels(self) -> dict[IntEnum, str]:
return {
# Translators: Sound split state
SoundSplitState.OFF: pgettext("SoundSplit", "Disabled"),
SoundSplitState.OFF: pgettext("SoundSplit", "Sound split disabled"),
SoundSplitState.NVDA_BOTH_APPS_BOTH: pgettext(
"SoundSplit",
# Translators: Sound split state
"NVDA in both channels and applications in both channels",
),
# Translators: Sound split state
SoundSplitState.NVDA_LEFT_APPS_RIGHT: _("NVDA on the left and applications on the right"),
# Translators: Sound split state
Expand All @@ -51,7 +58,11 @@ def _displayStringLabels(self) -> dict[IntEnum, str]:

def getAppVolume(self) -> VolumeTupleT:
match self:
case SoundSplitState.OFF | SoundSplitState.NVDA_LEFT_APPS_BOTH | SoundSplitState.NVDA_RIGHT_APPS_BOTH:
case (
SoundSplitState.NVDA_BOTH_APPS_BOTH
| SoundSplitState.NVDA_LEFT_APPS_BOTH
| SoundSplitState.NVDA_RIGHT_APPS_BOTH
):
return (1.0, 1.0)
case SoundSplitState.NVDA_RIGHT_APPS_LEFT | SoundSplitState.NVDA_BOTH_APPS_LEFT:
return (1.0, 0.0)
Expand All @@ -62,7 +73,11 @@ def getAppVolume(self) -> VolumeTupleT:

def getNVDAVolume(self) -> VolumeTupleT:
match self:
case SoundSplitState.OFF | SoundSplitState.NVDA_BOTH_APPS_LEFT | SoundSplitState.NVDA_BOTH_APPS_RIGHT:
case (
SoundSplitState.NVDA_BOTH_APPS_BOTH
| SoundSplitState.NVDA_BOTH_APPS_LEFT
| SoundSplitState.NVDA_BOTH_APPS_RIGHT
):
return (1.0, 1.0)
case SoundSplitState.NVDA_LEFT_APPS_RIGHT | SoundSplitState.NVDA_LEFT_APPS_BOTH:
return (1.0, 0.0)
Expand All @@ -85,15 +100,17 @@ def initialize() -> None:
log.exception("Could not initialize audio session manager")
return
state = SoundSplitState(config.conf["audio"]["soundSplitState"])
setSoundSplitState(state)
setSoundSplitState(state, initial=True)
else:
log.debug("Cannot initialize sound split as WASAPI is disabled")


@atexit.register
def terminate():
if nvwave.usingWasapiWavePlayer():
setSoundSplitState(SoundSplitState.OFF)
state = SoundSplitState(config.conf["audio"]["soundSplitState"])
if state != SoundSplitState.OFF:
setSoundSplitState(SoundSplitState.OFF)
unregisterCallback()
else:
log.debug("Skipping terminating sound split as WASAPI is disabled.")
Expand Down Expand Up @@ -153,11 +170,20 @@ def on_session_created(self, new_session: AudioSession):
channelVolume.SetChannelVolume(1, self.rightNVDAVolume, None)


def setSoundSplitState(state: SoundSplitState) -> dict:
def setSoundSplitState(state: SoundSplitState, initial: bool = False) -> dict:
applyToFuture = True
if state == SoundSplitState.OFF:
if initial:
return {}
else:
# Disabling sound split via command or via settings
# We need to restore volume of all applications, but then don't set up callback for future audio sessions
state = SoundSplitState.NVDA_BOTH_APPS_BOTH
applyToFuture = False
leftVolume, rightVolume = state.getAppVolume()
leftNVDAVolume, rightNVDAVolume = state.getNVDAVolume()
volumeSetter = VolumeSetter(leftVolume, rightVolume, leftNVDAVolume, rightNVDAVolume)
applyToAllAudioSessions(volumeSetter)
applyToAllAudioSessions(volumeSetter, applyToFuture=applyToFuture)
return {
"foundSessionWithNot2Channels": volumeSetter.foundSessionWithNot2Channels,
}
Expand Down
2 changes: 1 addition & 1 deletion source/config/configSpec.py
Expand Up @@ -58,7 +58,7 @@
audioAwakeTime = integer(default=30, min=0, max=3600)
whiteNoiseVolume = integer(default=0, min=0, max=100)
soundSplitState = integer(default=0)
includedSoundSplitModes = int_list(default=list(0, 1, 2))
includedSoundSplitModes = int_list(default=list(0, 2, 3))
# Braille settings
[braille]
Expand Down

0 comments on commit 25f562f

Please sign in to comment.