Skip to content

Temporarily suspend audio ducking when a 32 bit synthDriver is in use#19665

Merged
SaschaCowley merged 7 commits into
betafrom
suspendAudioDuckingForSapi32
Feb 23, 2026
Merged

Temporarily suspend audio ducking when a 32 bit synthDriver is in use#19665
SaschaCowley merged 7 commits into
betafrom
suspendAudioDuckingForSapi32

Conversation

@michaelDCurran

Copy link
Copy Markdown
Member

Link to issue number:

Partial fix for #19618

Summary of the issue:

As 32 bit sapi synthDrivers introduced in pr #19432 produce audio directly in their own process, NVDA currently cannot correctly duck audio when they are in use. Specifically, if NVDA is set to always duck, the audio from these synths is ducked along with other external audio. And if set to duck for speech and sounds, their audio does not cause ducking, and any NvDA sound that does, ducks their audio.
The correct approach to fix this for the long-term is to broker all 32 bit audio through NVDA, rather than it being played directly by the external process. See pr #19577. But until then, we should at least consider tempoarily disabling audio ducking while one of these synthDrivers is in use, so that its audio is not inappropriately ducked.

Description of user facing changes:

Description of developer facing changes:

Description of development approach:

  • Added a new private _AudioDuckingSuspender class to audioDucking which when at least one instance exists, temporarily suspends audio ducking, and disallows changing the current audio ducking setting via the gesture or GUI setting. When all instances are deleted, then audio ducking is restored back to the state it was before one or more instances were created.
  • _bridge's SynthDriverProxy class when instantiated now creates an instance of _AudioDuckingsuspender and holds it on the SynthDriverProxy instance, thus causing audio ducking to be temporarily disabled while this synthDriver is in use.

Testing strategy:

With a copy of NVDA that supports audio ducking:

  • Using eSpeak, set audio ducking via the gesture to always duck. Confirm that audio stays ducked.
  • Choose the sapi 32 bit synth from the Select Synthesizer dialog. Confirm that audio is no longer ducked.
  • Try to cycle through audio ducking modes with NVDA+shift+d. Confirm that NvDA reports that audio ducking is not supported.
  • Go to the audio pannel in the NvDA settings dialog. Confirm that the Audio ducking mode control is disabled.
  • Choose eSpeak from the Selected synthesizer dialog. Confirm that audio is again ducked.
  • Try to cycle through the audio ducking modes with the gesture. Confirm that this works.
  • Confirm that the audio ducking mode in the Audio panel of the NvDA settings dialog is no longer disabled.

Known issues with pull request:

  • This is a temporary partial fix that just ensures that audio ducking is correctly disabled. The full fix is to broker audio and again fully support audio ducking. PR Support for 32 bit sapi4 and sapi5 via a 32 bit synthDriver runtime #19432.
  • An alternative would be to grant the 32 bit synthDriver runtime process UIAccess and build audio ducking directly into it. However, adding a second process with UIAccess would greatly increase our possible attack surface, and is not moving in the direction of a secure add-on runtime.

Code Review Checklist:

  • Documentation:
    • Change log entry
    • User Documentation
    • Developer / Technical Documentation
    • Context sensitive help for GUI changes
  • Testing:
    • Unit tests
    • System (end to end) tests
    • Manual testing
  • UX of all users considered:
    • Speech
    • Braille
    • Low Vision
    • Different web browsers
    • Localization in other languages / culture than English
  • API is compatible with existing add-ons.
  • Security precautions taken.

…, as these synths currently produce audio from a separate process which can't duck and is inappropriatley cucked itself.
Copilot AI review requested due to automatic review settings February 23, 2026 01:21
@michaelDCurran michaelDCurran requested a review from a team as a code owner February 23, 2026 01:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a temporary suspension mechanism for audio ducking when 32-bit synthesizer drivers are in use. Since these drivers play audio directly in their own process (introduced in PR #19432), NVDA cannot correctly manage audio ducking for them. This is a temporary workaround until audio can be properly brokered through NVDA (planned for PR #19577).

Changes:

  • Added _AudioDuckingSuspender class with reference counting to temporarily disable audio ducking
  • Updated UI and keyboard shortcuts to indicate audio ducking is unsupported when suspended
  • Integrated suspender into SynthDriverProxy to automatically suspend ducking when 32-bit synth drivers are active

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
source/audioDucking.py Implements _AudioDuckingSuspender class with reference counting mechanism and suspension check function
source/gui/settingsDialogs.py Disables audio ducking mode control in settings when audio ducking is suspended
source/globalCommands.py Prevents cycling through audio ducking modes via keyboard gesture when suspended
source/_bridge/components/proxies/synthDriver.py Creates audio ducking suspender instance when proxied synth driver is initialized

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread source/audioDucking.py
Comment thread source/audioDucking.py Outdated
Comment thread source/audioDucking.py Outdated
Comment thread source/_bridge/components/proxies/synthDriver.py Outdated
Comment thread source/audioDucking.py Outdated
@seanbudd seanbudd added this to the 2026.1 milestone Feb 23, 2026
@SaschaCowley SaschaCowley merged commit b0228fe into beta Feb 23, 2026
73 of 75 checks passed
@SaschaCowley SaschaCowley deleted the suspendAudioDuckingForSapi32 branch February 23, 2026 06:13
seanbudd pushed a commit that referenced this pull request Feb 26, 2026
Follow-up to #19665
Summary of the issue:

#19665 prevents audio ducking when using a proxied SAPI4 or SAPI 5 speech synth, as it does not work correctly on betas due to the synth outputting sound out of process. However, as alpha builds broker the audio from from the 32-bit host process and output it in process, audio ducking works correctly.
Description of user facing changes:

Audio ducking again works on alpha builds when using a SAPI 4 or 32-bit SAPI 5 synth.
Description of developer facing changes:

None
Description of development approach:

Reverted the changes to source/_bridge/components/proxies/synthDriver.py introduced in b0228fe.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants