read it, hear it, say it, get graded

A free desktop app for learning to read and speak Mandarin

Read a Chinese book aloud and get every character graded.

Open any Chinese EPUB and the app splits it into short, speakable lines with tone-marked pinyin over every character. It reads each line in a neural Mandarin voice, records you saying it back, transcribes you with Whisper on your own machine, and marks each character right or missed. At 90% accuracy it moves to the next line on its own.

  1. 原来你不过是一个被经历塑造和被人影响的产物。21 chars
  2. 我wǒ们men常cháng说shuō某mǒu个gè国guó家jiā、8 chars
  3. 某个地区、某种教育,8 chars
  4. 甚至某种职业的人有很大不同。13 chars

Two sentences from the book in the screenshot below, run through the engine's chunk_text_for_learning() and annotate() on 2026-10-26. The second sentence breaks at its enumeration commas into units of 8, 8 and 13 characters; the pinyin comes from pypinyin, which reads each run of characters as a phrase so that characters with more than one reading get the right one.

The gap

Reading practice that checks what you said

I'm a Cantonese speaker from Hong Kong learning Mandarin, and I read Traditional characters more easily than Simplified. Most Chinese reading tools show the text and at best read it to you; checking whether what you said matched the characters on the page is left to a tutor, who costs money and keeps a schedule. This app does the mechanical part of that job (did you say the characters on screen?) for free, whenever you happen to be reading.

The loop

Read, listen, speak, get graded

The modern player's graded view: a large karaoke-style line with pinyin above every character, characters colored green, amber or red, faded context lines above and below, and an accuracy score on the transport bar.
The modern player's graded view, from docs/. The current line is large, the neighboring lines sit faded above and below, and the score shows on the transport bar.
Read
One unit at a time with tone-marked pinyin above each character. Short sentences are joined until a unit has at least 7 characters (up to 15); long sentences are never cut
Listen
Six edge-tts neural voices, four Mainland and two Taiwan, at 0.5×, 0.75×, 1×, 1.25× or 1.5×. Each line's audio is cached, so replays are instant
Speak
Press Record, read the line, press again. faster-whisper (the "small" model by default) transcribes the recording on your machine
Graded
Each character is marked right or missed, with an accuracy score. 90% or higher advances to the next line; this can be switched off
Script
OpenCC converts the whole book between Simplified and Traditional from a menu

The grader

Alignment, so one slip doesn't cascade

The grader aligns the transcript against the original with difflib.SequenceMatcher, so a skipped character doesn't shift every mark after it. Whisper often writes Mandarin in Traditional characters whatever the book uses, so both sides are converted to Simplified before comparing (学 and 學 count as the same), while the display keeps the book's own characters.

Lenient mode adds a sound check. Where the alignment finds a substitution, it compares the pinyin of the two characters, ignoring tone by default, and a match counts toward the score (amber in the app). Mandarin has many homophones, and a learner who said the right syllable has done what the exercise asks even when Whisper picks a different character.

Pick what Whisper heard for 我们常说某个国家

Heard
Graded

Every result here is the real output of grade() in mandarin_learner_engine.py, run on these six transcripts on 2026-10-28 and stored in the page; nothing is recomputed in the browser. Pinyin from the engine's annotate().

Day to day

It remembers where you were

Reopen the app and it returns to the same book, chapter and line, with your voice, speed and settings. Chapters are listed down the side, and pages that look like a cover, copyright notice or contents are flagged so you can skip them.

There are two interfaces over the same engine: a media-player layout with a karaoke-style stage, and a classic reader. Both have light and dark themes and keyboard shortcuts for every control. A command-line tool exposes the engine directly for listing chapters, previewing units and pinyin, and testing the grader.

The reading view: the current sentence large with pinyin above each character, the previous and next sentences faded above and below, and a round play button with keyboard shortcuts on every control.
The reading view before you speak. Each button shows its shortcut.

Limitations

It grades characters and leaves tones unchecked

The score compares what Whisper heard with the characters on screen, which makes it a proxy for pronunciation; it does not assess tones. Whisper can be more forgiving than a native listener, and it can also mishear a correct reading. Lenient mode ignores tones by default when it compares pinyin.

Audio comes from Microsoft's online edge-tts service, so each new line needs a connection the first time it is played. Speech recognition runs offline after a one-time model download. The app ships no books: you supply your own EPUBs.

Built with

Python on your own machine, no cost

EPUB
ebooklib and BeautifulSoup for the spine, table of contents and text
Pinyin
pypinyin, phrase-aware for characters with several readings
Speech
edge-tts neural voices (online); faster-whisper speech-to-text (offline), with openai-whisper as a fallback
Grading
difflib alignment, OpenCC script normalization, optional pinyin match
Interface
Tkinter, two layouts; sounddevice for the microphone, pygame for playback
Sibling
Cantonese Learner V2, the same loop for Cantonese with daily Hong Kong news; EPUB to Audiobook, whose pipeline this reuses

Learn from a book you want to read