Skip to content

Kindle native TTS fails on KT6 (Kindle 11th gen 2024) / firmware 5.19.6 — LIPC + ttssrc API mismatch #77

Description

@0xbartita

Plugin: v0.1.17.46
KOReader: v2026.07.1
Device: Kindle 11th gen 2024 (KT6), MT8110 Bellatrix, androidboot.hardware=mt8512, armv7l
Firmware: 5.19.6 (Kindle 5.19.6 (483254 042)), kernel 4.9.77-lab126

Summary

On KT6 / 5.19.6 the Kindle native TTS engine always fails with "The text-to-speech engine could not produce audio." All four native strategies in the bug report return 0. This looks like an Amazon API change in 5.19.x rather than a missing dependency — every component the native path needs is present and loads correctly.

espeak-ng works. Piper is too slow on this SoC (see below). Native is the only broken engine.

Everything the native path needs is present

Component Status
/usr/lib/tts/libIvonaEInkAPI.so.1.0, libIvonaEInkCommon.so.1.0, libtts_engine.so present, preload OK
ttssrc (/usr/lib/gstreamer-1.0/libgstttssrc.so) found
mixersink (/usr/lib/gstreamer-1.0/libgstmixersink.so) found
audiomgrd, btfd, playermgr running
Voice data /tts/conf/en_us_joanna.json (+ de/es/fr/it/pt) present
TTS orchestrator voices enumerated OK (bianca/it_it etc.)
A2DP control sockets live — @/data/misc/bluedroid/.a2dp_ctrl

So this is not "no audio player found" and not a Bluetooth problem.

Failure 1 — ttssrc rejects content-texts

Running the bundled helper directly:

# kindle/gst-play-native --ttssrc "pronunciation"
gst-play: preloaded /usr/lib/tts/libIvonaEInkAPI.so.1.0
gst-play: preloaded /usr/lib/tts/libIvonaEInkCommon.so.1.0
gst-play: loaded libgstreamer-1.0.so (0.0)
gst-play: ttssrc pipeline: ttssrc content-texts="pronunciation" ! audio/x-raw,format=(string)S16LE,rate=(int)24000,channels=(int)1,layout=(string)interleaved ! mixersink stream-type=Music sync=true
gst-play: GStreamer error: No content texts specified for TTS.
gst-play: debug: gstttssrc.c(328): gst_tts_src_start (): /GstPipeline:pipeline0/GstTTSSrc:ttssrc0

The property is set on the command line, yet gst_tts_src_start() reports it empty. gst-inspect-1.0 ttssrc on this firmware does not list content-texts among the element properties. The wrapped nix gst-play fails identically, so it is not loader- or glibc-related.

Failure 2 — LIPC orchestrator has no speak property

From the bug report:

tts_speak = com.lab126.tts.orchestrator failed to set value for property speak (0x8 lipcErrNoSuchProperty)
tts_state_after=0
inplayback_after=0

And all native strategies fail:

Strategy A: PlayParameter only            tts_a=0  ip_a=0
Strategy B: Open+PlayParameter+Play       tts_b=0  ip_b=0
Strategy C: PlayParameter+Play            tts_c=0  ip_c=0
Strategy D: Open+PlayParameter+Play(empty)

Secondary — probe order picks the binary without Ivona preloaded

_detectKindleGstPlay() breaks on the first candidate reporting mixersink=found. Both of these report it, but only the native build preloads the Ivona libraries:

candidate 2  (nix gst-play + bundled linker)      candidate 4  (gst-play-native)
  glibc=2.42                                        build=native
  gstreamer=loaded                                  glibc=2.35
  mixersink=found                                   gstreamer=loaded
  ttssrc=found                                      mixersink=found
  (no Ivona preload)                                ttssrc=found
                                                    preloaded libIvonaEInkAPI.so.1.0
                                                    preloaded libIvonaEInkCommon.so.1.0

Candidate 2 wins the loop, so the selected binary never has Ivona loaded. It does not change the outcome here (both fail at gst_tts_src_start), but on a firmware where content-texts works, this ordering would still pick the Ivona-less binary.

Also: wavparse=not_found on this firmware, in both candidates.

Failure 3 — native TTS is attempted even when tts_backend = "piper"

With ["tts_backend"] = "piper" in settings.reader.lua, crash.log still shows on nearly every sentence:

ERROR TTSEngine: Kindle native TTS -- no text to speak
WARN  TTSEngine: espeak fallback synthesis for cold-start
WARN  SyncController: Piper gap padded in audio ( sentence ), delay=0.05s

Failure 4 — playback torn down mid-sentence by on_close

WARN  SyncController: stop() from state= playing sentence= 1 / 9 caller:
stack traceback:
    plugins/audiobook.koplugin/synccontroller.lua:1458: in function 'on_close'
    plugins/audiobook.koplugin/audiobookplayer.lua:874: in function 'onClose'
    plugins/audiobook.koplugin/audiobookplayer.lua:1797: in function 'handleEvent'

Also seen at sentence= 3 / 6.

Piper is not viable on this SoC

The plugin's own watchdog fires: "Piper neural TTS could not keep up on this device: it still had not produced any audio after 2 minutes of espeak fallback." This is with the bundled en_US-danny-low, already the fastest quality tier. Worth noting in the docs that KT6-class hardware is espeak-only in practice.

Orphan espeak processes survive playback

Three espeak-ng processes were left with PPid: 1 after sessions ended, one predating the running KOReader instance by ~40 minutes. Killing them is currently manual / requires a KOReader restart.

What works

Bundled espeak-ng synthesizes correctly via its own loader:

espeak-ng/lib/ld-linux-armhf.so.3 --library-path espeak-ng/lib \
  espeak-ng/bin/espeak-ng --path=espeak-ng/share "pronunciation test" -w /tmp/t.wav
→ /tmp/t.wav, 64098 bytes

Attachments

I have both files ready with the device serial redacted and will attach them to this issue:

  • audiobook-bug-report-20260829-141710.txt (from generate-report.sh, plugin v0.1.17.46)
  • crash.log (2423 lines, captured before restarting KOReader)

Happy to run further commands on the device — I have root SSH access to it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions