Skip to content

Support pitch change for capitals and rate boost (SAPI5 only) for 32 bit SAPI synths#19541

Merged
SaschaCowley merged 6 commits into
betafrom
i19529
Feb 3, 2026
Merged

Support pitch change for capitals and rate boost (SAPI5 only) for 32 bit SAPI synths#19541
SaschaCowley merged 6 commits into
betafrom
i19529

Conversation

@michaelDCurran

@michaelDCurran michaelDCurran commented Feb 2, 2026

Copy link
Copy Markdown
Member

Link to issue number:

Fixes #19529

Summary of the issue:

PR #19432 added back support for 32 bit sapi synths via a 32 bit shim. However, in-stream synth parameter changes (E.g. pitch changes for capital letters) was not implemented, and therefore pitch would never change when speaking a capital letter.

Description of user facing changes:

Description of developer facing changes:

Description of development approach:

  • synthDriverHost: when creating a synth driver and returning it to NVDA, also locally track it as the active synth in the host by setting synthDriverHandler._curSynth. this allows synthDriverhandler.getsynth() to return the synth inside the 32 bit host. Needed to fetch the synth's name for config value lookup via synth commands.**
  • Support all built-in synth commands (I.e. index, break, langChange, characterMode, pitch, rate, volume and phoneme) on 32 bit synthDrivers proxied to NvDA. This includes correctly expsing the supportedCommands property, and a much better serialization / deserialization in speak, which no longer uses Pickle, but instead json, fully supporting all the synth commands. This lallows pitch changes for capital letters among other things.**
  • sapi4 synthDriver: when fetching rate, pitch and volume values, ensure that the raw values are clipped to the min and max values before converting to percentage. Sometimes the raw value was outside the min max range and was producing values higher than 100%.
  • Add missing rateBoost getter / setter on SynthDriver proxy. This allows rateBoost to fully function on 32 bit sapi5.

Testing strategy:

  • Switch to sapi4.
  • Open notepad.
  • Type Hh. (The first h being capitalized).
  • Use left and right arrows to move to each character, having NVDA speak it. Ensure that the pitch is raised for the capital h and back to normal for the second h.

Known issues with pull request:

None known.

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.

…A, also locally track it as the active synth in the host by setting synthDriverHandler._curSynth. this allows synthDriverhandler.getsynth() to return the synth inside the 32 bit host. Needed to fetch the synth's name for config value lookup via synth commands.
…haracterMode, pitch, rate, volume and phoneme) on 32 bit synthDrivers proxied to NvDA. This includes correctly expsing the supportedCommands property, and a much better serialization / deserialization in speak, which no longer uses Pickle, but instead json, fully supporting all the synth commands. This lallows pitch changes for capital letters among other things.
…e that the raw values are clipped to the min and max values before converting to percentage. Sometimes the raw value was outside the min max range and was producing values higher than 100%.
Copilot AI review requested due to automatic review settings February 2, 2026 02:22
@michaelDCurran michaelDCurran requested a review from a team as a code owner February 2, 2026 02:22

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 fixes the capital pitch change feature for 32-bit SAPI synthesizers by implementing proper support for synth commands (particularly PitchCommand) in the 32-bit synth driver bridge. The original 32-bit synth support (PR #19432) did not implement in-stream synth parameter changes, causing pitch changes for capital letters to fail.

Changes:

  • Added support for serializing/deserializing all built-in synth commands (IndexCommand, BreakCommand, LangChangeCommand, CharacterModeCommand, PitchCommand, RateCommand, VolumeCommand, PhonemeCommand) in the bridge between NVDA and the 32-bit synth driver host
  • Implemented config tracking in the 32-bit host to ensure prosody commands can access current default settings
  • Fixed SAPI4 synth driver to clamp raw rate, pitch, and volume values within min/max bounds before converting to percentages

Reviewed changes

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

File Description
source/_synthDrivers32/sapi4.py Added clamping of raw rate, pitch, and volume values to prevent values outside min/max range from producing incorrect percentages
source/_bridge/runtimes/synthDriverHost/synthDriverHost.py Sets synthDriverHandler._curSynth to track the active synth locally in the 32-bit host, enabling getSynth() to work for config lookups
source/_bridge/components/services/synthDriver.py Added getSupportedCommands method, JSON-based deserialization for all synth commands, config initialization and updates for prosody command defaults
source/_bridge/components/proxies/synthDriver.py Added getSupportedCommands property, JSON-based serialization for all synth commands, cache invalidation for supported commands on voice change
Comments suppressed due to low confidence (1)

source/_bridge/components/services/synthDriver.py:131

  • Type mismatch: The proxy is sending bytes (json.dumps().encode("utf-8")), but the service method signature expects a string (data: str). While RPYC may handle the conversion automatically, this creates a type inconsistency. Consider either removing the .encode("utf-8") call on the proxy side (line 201) or changing the service signature to accept bytes and explicitly decode them. For clarity and maintainability, the types should match the actual data being sent.

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

Comment thread source/_bridge/components/services/synthDriver.py Outdated
Comment thread source/_bridge/components/services/synthDriver.py
Comment thread source/_synthDrivers32/sapi4.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@makhlwf

makhlwf commented Feb 2, 2026

Copy link
Copy Markdown
Contributor

Is it possible to fix the speed boost not working in Speech API 5 32-bit? Currently, the setting isn't effective at all. Even with this pull request, I tried the build which was generated via the actions in GitHub.

@michaelDCurran

Copy link
Copy Markdown
Member Author

@makhlwf I've now added the missing getter / setter for rateBoost which allows rateBoost to fully work for 32 bit sapi5. I had already done the work to ensure Sonic was available in 32 bit, I just hadn't added the getter and setter on the proxy it seems.

@SaschaCowley SaschaCowley added this to the 2026.1 milestone Feb 2, 2026
@seanbudd seanbudd added the conceptApproved Similar 'triaged' for issues, PR accepted in theory, implementation needs review. label Feb 3, 2026
@SaschaCowley SaschaCowley changed the title Support pitch change for capitals for 32 bit SAPI synths Support pitch change for capitals and rate boost for 32 bit SAPI synths Feb 3, 2026
@SaschaCowley SaschaCowley changed the title Support pitch change for capitals and rate boost for 32 bit SAPI synths Support pitch change for capitals and rate boost (SAPI5 only) for 32 bit SAPI synths Feb 3, 2026
@SaschaCowley SaschaCowley merged commit 71294e4 into beta Feb 3, 2026
53 of 57 checks passed
@SaschaCowley SaschaCowley deleted the i19529 branch February 3, 2026 06:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

conceptApproved Similar 'triaged' for issues, PR accepted in theory, implementation needs review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants