Project context and disclosure boundary
The project addressed offline text-to-speech on an RK3588-S smart terminal. Model packaging, streaming callbacks, playback control, male and multiple female voice selection, an AAR and a Demo APK were implemented for Android 12 and arm64-v8a with ordinary application permissions. WAV files and performance records were produced on the physical device. Customer names, asset identifiers and business text have been removed; only facts traceable to code, builds, logs and audio files are disclosed.
Engineering objectives
- Convert text to speech locally when a network is unavailable.
- Expose a stable asynchronous streaming PCM interface through an Android AAR.
- Provide a selectable Chinese male voice and multiple Chinese female voices.
- Deliver a demo, integration guide, licences, WAV samples and traceable test records.
On-device processing path
A text request first enters the task scheduler, where a new request can stop active or queued older text. The non-quantized Kokoro model loads when the SDK is created. Floating-point output is converted to 24 kHz mono PCM16 little-endian chunks and returned to AudioTrack or a file wrapper. No cloud TTS API is called in the synthesis path.
- The app submits text, voiceId, rate and volume.
- The SDK validates parameters and manages stop, replacement and queue state.
- Kokoro runs local CPU inference on RK3588-S.
- onAudioChunk() returns PCM chunks; onCompleted() reports completion statistics only.
- The app plays raw PCM or adds a WAV header before saving.
Android SDK delivery
The standalone TTS AAR retains the EyeTtsSdk, TtsOptions, TtsStreamCallback and TtsAudioData interfaces. replaceTextStreamAsync() stops older text and synthesizes the newest request; stopTts() stops synthesis and clears queued work. The SDK returns raw PCM rather than a WAV file with a header.
TtsOptions options = new TtsOptions("zm_009", 1.0f, 1.0f);
tts.replaceTextStreamAsync(text, options, callback);
// callback.onAudioChunk(... TtsAudioData audio)
Male voice capability and device test
The male voice is a tested capability, not a placeholder. The disclosed voice is zm_009, speaker ID 58. It generated the same sentence at 0.8x, 1.0x and 1.4x on RK3588-S. All three WAV files are 24 kHz, mono PCM16 with zero clipped samples. Durations were 5.549, 4.363 and 3.086 seconds, confirming that the rate control changed the output. These measurements do not replace human listening assessment.
Male zm_009 / 0.8x
Male zm_009 / 1.0x
Male zm_009 / 1.4x
Multiple female voices
SDK 0.5.1 maps all 55 official Chinese female voice names and keeps the female alias mapped to zf_001. The Demo exposes 12 female candidates and each was rendered to WAV on RK3588-S. The public table uses zf_001 as a baseline. Different durations, peaks and hashes rule out duplicate exports, but do not prove naturalness, intelligibility or suitability for a specific business context.
Female zf_001 / 1.0x
Hardware and software environment
| Item | Measured value |
|---|---|
| SoC | RK3588-S |
| OS | Android 12 |
| ABI | arm64-v8a |
| Model | Kokoro multi-lang v1.1, non-quantized |
| Runtime | sherpa-onnx 1.13.4, CPU, 4 threads |
| Output | 24000 Hz, mono, PCM16 little-endian |
Measured RK3588-S results
| Voice / rate | First PCM | Total | Audio | RTF | Clipping |
|---|---|---|---|---|---|
| Female zf_001 / 1.0x | 1572 ms | 4387 ms | 4.241 s | 1.034 | 0 |
| Male zm_009 / 0.8x | 1923 ms | 5534 ms | 5.549 s | 0.997 | 0 |
| Male zm_009 / 1.0x | 1545 ms | 4396 ms | 4.363 s | 1.008 | 0 |
| Male zm_009 / 1.4x | 1133 ms | 3201 ms | 3.086 s | 1.038 | 0 |
The test sentence was a short Chinese streaming-TTS phrase. Four CPU threads and SDK volume parameter 1.0 were used. First chunk is the time to the initial PCM callback; RTF is total generation time divided by audio duration. Source: Winge RK3588-S project test record dated 2026-08-05. The sample is small and does not establish performance for every text or device.
Tests and deliverables
- EyeAlgo TTS Android AAR and the matching Core AAR.
- Demo APK for text, male/female voice, rate, volume, play, pause, stop and WAV export.
- Kokoro inventory with file sizes and SHA-256 checks.
- Male and female device WAV files, logs, build tests and integration guide.
- Third-party notices for sherpa-onnx, ONNX Runtime and the model.
38 test suites / 185 test cases / 0 failures / 0 errors / 0 skipped. AAR and APK builds passed.
Applicable scenarios
The implementation can be evaluated for smart-glasses prompts, offline OCR reading, industrial handhelds, equipment alerts, exhibition terminals and Android devices on isolated networks. Real-time dialogue, long-form reading and production firmware require separate evaluation against package size, memory, first-chunk latency, audio hardware, text normalization and stability targets.
Integration conditions
- The tested target is Android 12 and arm64-v8a; other environments require compatibility validation.
- The non-quantized AAR is about 354 MiB and the Demo APK about 360 MiB, so storage and distribution must be planned.
- The host project must not package conflicting sherpa-onnx Java/JNI or ONNX Runtime versions.
- AudioTrack must use 24000 Hz, mono, PCM16 little-endian.
- Production acceptance requires a frozen text set, voices, rates, playback hardware, latency and stability criteria.
Limits and acceptance boundary
- Current status is CUSTOMER_TEST / NOT_PRODUCTION.
- No 100-item Chinese, English, number, punctuation and long-text intelligibility test is complete.
- No eight-hour continuous synthesis, stop, preemption and playback stability test is complete.
- Human ranking of every voice and the default female voice remain open.
- INT8 size, latency, memory and quality comparison and production signing remain open.
- Non-quantized first-chunk P95 and RTF were slightly above the original targets and cannot be reported as a passed performance gate.
Public technical references
Voice IDs, Android configuration and sample rate are based on the sherpa-onnx Kokoro multilingual model documentation. Model origin and licence are referenced from the Kokoro-82M-v1.1-zh page. Upstream documentation is used to identify the component; it is not treated as acceptance evidence for this delivery.
Frequently asked questions
Does the SDK work fully offline?
The current synthesis path loads the model and generates PCM locally without a cloud TTS call. Initial app or model distribution and business data synchronization depend on the deployment design.
Was the male voice tested on a physical RK3588-S?
Yes. zm_009, speaker ID 58 was generated at 0.8x, 1.0x and 1.4x, with first-chunk, total time, duration, RTF and clipping checks. Long-text and eight-hour stability acceptance are still open.
How many Chinese female voices are supported?
Version 0.5.1 maps 55 official Chinese female names and the Demo presents 12 candidates. Mapping does not mean every voice has passed subjective acceptance; selected voices should be retested with business text.
Does the streaming callback return a WAV file?
No. onAudioChunk() returns raw 24 kHz mono PCM16 little-endian data. It can be written to AudioTrack, or a standard WAV header can be added when saving.
Why is it not labelled production-ready?
Evidence covers builds, unit tests, the model inventory, short-sentence device synthesis and format checks, but not long text, all voices, eight-hour stability, production signing or the customer's audio chain.
Online
Phone
WeChat
Top