Skip to content

Preserve voice parameters when changing between SAPI4/SAPI5 voices with synth settings ring#17700

Merged
seanbudd merged 4 commits into
nvaccess:masterfrom
gexgd0419:preserve-sapi5-settings
Feb 16, 2025
Merged

Preserve voice parameters when changing between SAPI4/SAPI5 voices with synth settings ring#17700
seanbudd merged 4 commits into
nvaccess:masterfrom
gexgd0419:preserve-sapi5-settings

Conversation

@gexgd0419

@gexgd0419 gexgd0419 commented Feb 15, 2025

Copy link
Copy Markdown
Contributor

Link to issue number:

Fixes #17693. Fixes #2320.

Summary of the issue:

When using the synth settings ring to switch to another SAPI4/SAPI5 voice, its parameters such as rate and volume will be reset to the default value.

This is because the synth driver destroys and re-creates the SAPI object when changing the voice, which resets all its parameters. Then the synth driver selects the correct voice, but other parameters are not preserved.

Changing the voice with the settings dialog works, because the settings dialog reads the property values and assigns them to the slider controls in order to display them, which triggers the event of the slider controls, which assigns the property values just read from the synth back to the synth, which refreshes the property values and therefore "fixes" the problem.

However, when using the synth settings ring, only the voice property is changed. Other properties are not refreshed, which makes the issue appear.

Description of user facing changes

The SAPI4/SAPI5 synthesizer will be able to preserve the settings when switching between voices.

Description of development approach

SAPI5:

In _set_voice, after using _initTts to re-create the SAPI5 object and select the voice, restore the rate and volume parameters to the value stored previously. Pitch does not need to be restored, as it is not a parameter of the SAPI5 object.

SAPI4:

For volume, the percentage is preserved, so that 80% volume is always 80% of the voice's volume range.

For rate and pitch, the difference (delta) between the current value and the default value is preserved. If the rate is set to be 50 WPM faster, when switched to another voice, the rate will also be 50 WPM faster.

Testing strategy:

Tested manually.

Known issues with pull request:

None.

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.

@coderabbitai summary

@gexgd0419

gexgd0419 commented Feb 15, 2025

Copy link
Copy Markdown
Contributor Author

The problem with SAPI4 voices is that there's no fixed range for the parameters, which means that different voices may have different minimum, maximum, and default values for rate, volume, pitch, etc.. This makes applying the same parameter across different voices difficult. When switching between voices, what should we preserve, the absolute value, or the relative percentage like in SAPI5?

For volume, we may want to preserve the relative percentage, so that 80% volume is always 80%, no matter the minimum and maximum volume.

For speed, the unit is words per minute. Should we preserve the words per minute, or preserve the relative percentage, because different voices may have different default speeds?

For pitch, the unit is hertz. We may want to preserve the relative percentage, because male and female voices have different default pitches. We don't want to make male voices use the same high pitch as female voices, or vice versa.

Another problem is that using relative percentage will change the meaning of the parameter values. For a male voice, a pitch of 40 might used to be too high, but now 50 means the default pitch, which may confuse users, and cause problems when upgrading.

I would like to hear your thoughts about this. As SAPI4 is being deprecated, we may also choose to not fix this for SAPI4.

cc @SaschaCowley @LeonarddeR @jcsteh

@gexgd0419 gexgd0419 changed the title Preserve voice parameters when changing between SAPI5 voices with synth settings ring Preserve voice parameters when changing between SAPI4/SAPI5 voices with synth settings ring Feb 15, 2025
@gexgd0419

Copy link
Copy Markdown
Contributor Author

For SAPI4, I decided to preserve percentage for volume, and preserve the difference between current value and default value for rate and pitch, without changing the meaning of the parameter value.

@gexgd0419 gexgd0419 marked this pull request as ready for review February 15, 2025 04:47
@gexgd0419 gexgd0419 requested a review from a team as a code owner February 15, 2025 04:47
@jcsteh

jcsteh commented Feb 15, 2025

Copy link
Copy Markdown
Contributor

Personally, I'm not convinced we should preserve the values at all, precisely because different voices can apply different values very differently. With a synth like eSpeak or even OneCore or Vocalizer, it's okay because the voices respond to parameter values fairly consistently; all the voices effectively use the same underlying engine by the same vendor. With SAPI4 and SAPI5, this is not true at all: two different voices could have two entirely different synthesis engines. Rate 100 with one voice could be twice as fast as some other voice. I realise users find the current behaviour surprising, but my feeling is that we're just going to replace one surprising behaviour with another and we'll get bugs like "the voice is unintelligibly fast when I switch voices with SAPI5".

@gexgd0419

Copy link
Copy Markdown
Contributor Author

#17693 reports a problem that the rate value may become out of sync with the actual rate when switching to another SAPI5 voice. That's because when implementing rate boost for SAPI5, the rate value is changed to be stored inside a variable, which isn't reset when calling _initTts.

If we should reset all parameters when switching between SAPI4/SAPI5 voices, I will make another PR that resets the rate value properly and turns off rate boost consistently when switching voices.

Thanks for your insight. I will wait to see what others think about this.

@seanbudd seanbudd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks @gexgd0419 !

@seanbudd seanbudd merged commit e8b2c85 into nvaccess:master Feb 16, 2025
@github-actions github-actions Bot added this to the 2025.1 milestone Feb 16, 2025
@gexgd0419 gexgd0419 deleted the preserve-sapi5-settings branch February 17, 2025 01:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants