← Technical Information

Text-to-Speech Narration

The spoken track behind every animation, generated fully automatically.

Three Stages

All three animation types (simulated, observed, and ground motion decay — see Physics Animation (Blender)) include a spoken narration track describing the earthquake and its local impact. The narration is generated fully automatically in three stages:

  1. City enrichment via local LLM. Basic information about the affected city (county, state classification, and a brief notable characteristic) is obtained from a locally-hosted language model — see Local Language Model. The model is never called for earthquake intensity calculations; it is used only to supply geographic context for cities where strong shaking was estimated. All LLM responses are validated and normalised before use; if the model is unavailable or returns an unusable response, generic text is substituted automatically.
  2. Speech-friendly text normalization. Before synthesis, the narration text is rewritten so every element is spelled out the way a person would say it: clock times become words ("two thirty four in the morning"), dates use ordinal words ("December twentieth twenty twenty two"), magnitudes are expanded ("magnitude six point four"), and seismic station codes are spelled letter by letter (e.g. "BK.BARR.HNE" → "B K, B A R R, H N E"). A city/state comma is dropped and a bare state abbreviation expanded ("Redwood Valley, CA" → "Redwood Valley California") because the TTS engine reads a comma as a pause and produces an audible stumble mid-placename. This keeps the spoken track clear and unambiguous.
  3. Text-to-speech synthesis. The normalized narration is converted to an MP3 audio file using Kokoro, an open-weight 82-million-parameter neural text-to-speech model running locally via the ONNX runtime — no third-party API calls are made and no audio leaves the server. The synthesised audio is muxed into the MP4 with ffmpeg so it plays from the start of the animation; if the narration outlasts a short animation, the final video frame is held until the narration completes.

Voice Options

Kokoro ships a set of built-in voices; Intensity Lab currently narrates with a single configured voice (am_michael by default), set via an environment variable rather than hardcoded, so a different voice can be selected without a code change if narration quality needs adjusting for a particular audience.

Kokoro replaced an earlier Coqui TTS engine, which required an older Python version; Kokoro has no such dependency and its model files are baked directly into the deployed image, so narration never depends on a runtime model download.