Skip to content

Add optional Speak numbers as digits setting - #439

Open
mg-bledig wants to merge 2 commits into
trypsynth:masterfrom
mg-bledig:feature/speak-numbers-as-digits
Open

mg-bledig wants to merge 2 commits into
trypsynth:masterfrom
mg-bledig:feature/speak-numbers-as-digits

Conversation

@mg-bledig

Copy link
Copy Markdown
Contributor

Summary

Implements the Speak numbers as digits feature discussed in #418.

The feature adds an optional setting under Verbosity, disabled by default, allowing consecutive digits to be spoken individually rather than as whole numbers.

For example, 283482 is prepared for speech as 2 8 3 4 8 2.

Existing digit groupings are preserved. The transformation affects only speech; the original text, copied content and accessibility navigation remain unchanged.

Implementation

Following Quin's suggestion in #418, I investigated Android's TtsSpan.DigitsBuilder.

Testing with Vocalizer Tessa showed that this approach did not produce the desired digit-by-digit pronunciation. However, inserting ordinary spaces between digits worked.

The implementation therefore prepares a speech-only representation while preserving the original text.

Because inserting spaces changes text length, the implementation also handles speech-position mapping, chunking, existing text spans and pause/resume behaviour.

The feature is disabled by default, preserving existing speech behaviour.

Testing

Tested on:

  • Oppo CPH2197
  • Android 13
  • Vocalizer Tessa

The feature successfully reads numbers as individual digits when enabled and returns to normal number pronunciation when disabled.

The corrected APK was installed and tested on the physical device.

Automated verification:

  • 1,166 unit tests passed, including 52 focused test cases.
  • Phone debug APK built successfully.
  • Phone and watch lint checks passed.
  • GitHub Actions Build workflow passed, including unit tests, lint, debug APK builds and the build without Play services.

Known limitations

Punctuation pronunciation depends partly on the speech synthesizer. With Vocalizer Tessa, punctuation such as commas and decimal points required Vocalizer's own punctuation-processing option to be enabled before being announced.

If an app-supplied speech replacement crosses a speech-chunk or resume boundary, the incomplete replacement is discarded for that portion, allowing the visible text to be spoken instead.

Setting placement and quick access

In issue #418, I originally proposed implementing this as a reading control so users could toggle digit reading quickly using the existing navigation gestures.

The current implementation places the option under Verbosity instead. After testing it, I'm comfortable with that location, although switching the feature on or off requires navigating through Settings.

For time-sensitive situations such as entering OTPs, a quicker toggle would be useful.

I'd appreciate your thoughts on whether the current placement is appropriate or whether the feature would be better implemented as a reading control. I'm happy to follow your preference on this.

Feedback welcome

I'm not entirely convinced that inserting spaces is the best possible approach, and I suspect there may be a cleaner way to achieve the same result.

However, this is an approach I've found that works with my speech synthesizer.

I'd particularly appreciate feedback on whether the speech transformation and its handling of offsets and spans fit appropriately within BackTalk's architecture.

I'm very open to suggestions for a simpler or more suitable implementation.

Keep the opt-in spacing behavior tested on the Oppo with Google TTS
and Vocalizer Tessa. Align the setting summary with the adjacent letters,
currency symbols and numeric punctuation it separates.

Move this feature's own helper and tests to Kotlin without changing the
algorithm, add preference and engine-submission tests, and retain all
original regression cases. Leave Google's Java files unchanged.

Native digits spans worked in the standalone Google test but did not
reliably give individual digits with the tested Tessa setup. Spacing was
more predictable in those tests; neither approach promises identical
pronunciation across engines, punctuation settings or voices.
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.

1 participant