It reads this page. Paste a URL and it reads that instead. Rendered once, kept as a file, in one voice or in two at the same time.
try:
A reader that speaks a document aloud and lights each block as it goes. By default the document is this one — the page reads itself, the way docsreader reads its own README — and the address bar swaps in any other page you point it at. Clear the box and it comes back here.
The wait before the first word is not the download, it is the synthesis: NEURAL runs at about 2.8 times realtime here, so a long page is minutes of work before a single sample exists. So a long document is rendered in parts — the first one short enough to come back in seconds and start playing, each later one made while the one before it plays. Joins fall on block boundaries, which end in silence anyway, and the next file is pulled into your browser's cache while the current one is still playing, so a handover is not a fetch.
The parts double in size, and that is the whole trick. A first part small enough to start quickly is, by exactly that smallness, too small to cover what comes after it — this page shipped for a day as one short lead and one long tail, and on itself that meant 33 seconds of audio followed by nearly two minutes of silence while the rest was still being made. Since synthesis runs at 2.8× realtime, a part that is twice its predecessor takes about 0.7 of its playing time to make, so it lands with roughly 30% to spare, and every seam after the first has more slack than the one before it. On this page: first audio at 11 seconds, six parts, tightest margin 18 seconds. If a part is late anyway — a busy renderer, someone else's document ahead of yours — the page says so and carries on by itself rather than simply stopping.
The block being read is lit, and the word inside it a little brighter. Be clear about where that comes from: the block times are real — the renderer knew the exact second each one began, because it was writing the samples. There are no word times, and there is no honest way to invent them; what you see is an estimate across a known span, weighted by word length and by the pauses punctuation buys. What keeps it from wandering is that it is re-anchored every block, so the error can never accumulate past one paragraph. Under MONY it is looser still, because two voices inside one paragraph are not saying the same word at the same moment — that is the point of them.
Under the transport is the same reading in the fixed point the rest of the DeltaVerse uses:
eighteen decimals, which is what ChronosOracle values a second in (1e18 per
second, decimals() = 18) and what the oscilloscope encodes every acoustic metric in
before it hashes a voiceprint. A reader that reports its position only in minutes and seconds is
speaking a different language from the two things that will be asked to attest to it.
Where the digits come from, because eighteen of them is a claim. currentTime
is a double, and printing eighteen decimals of a double is printing four or five digits of
floating-point noise and calling it precision. The audio clock has a real quantum and it is not the
double — it is the sample. At 24 kHz one sample is 41,666,666,666,666 wei, and a position
quantised to the sample converts exactly as an integer ratio: wei = sample × 1018 ÷
rate. Every one of the eighteen digits is entailed by the sample index and the rate, and the
readout prints the sample so you can check it rather than believe it. CHRONOS is the unix
second — millisecond is all a browser clock offers, so the twelve digits below it are zero rather
than invented. KAIROS is sequence rather than duration: which part, which block, which
sample.
The first press sends the text to be synthesised and gets back an ordinary Ogg file. That file is kept — on the server, keyed by a hash of the exact text and voice, and its address is remembered here in your browser. Every play after the first is a plain audio fetch: no synthesiser, no wait, no CPU on anyone's machine. Change a word and the hash changes with it, so a stale recording can never be served for text that no longer exists.
NEURAL is the reference and the default, on every page and after every refresh — piper
en_GB-alan-medium, the same model the DeltaVerse store is rendered from.
JAIMLA is the female voice, and she is saved in her own right rather than derived. She used to be neural with a ratio applied — a shade slower, a shade lower — which is a male voice pitched down under a woman's name. Pitch is not gender: lowering a male voice drags its formants down and produces a larger man. What carries gender is which voice is chosen, so she selects a female model rather than multiplying a male one.
LEADER is one accent assembled from eight world Englishes — royal, US, Australian, Indian, Mexican, Brazilian, Brooklyn, Slavic — and it is the deepest and slowest voice in the set.
MONY is the other two at once, and it is a harmony rather than a pile-up for a measured reason: near an octave apart, though not as near as this page used to claim. Measured here over six sentences, neural's median pitch is 96 Hz and jaimla's 182 — a ratio of 1.88, which is about a semitone short of a true octave. The earlier figures (94.6 and 183.8) gave 1.943, and that is fifty cents flat, not the eleven this page asserted; the arithmetic was simply wrong. Jaimla also ranges widely, 168 to 206 across those same six sentences, so "an octave" was always a convenient description of a moving thing rather than a constant. Near enough that the two stack instead of clashing, which is the part that matters — and far enough that calling it an octave would be flattering it.
They are rendered into separate channels and mixed here, not there. A balance baked in at render time is a balance nobody can move afterwards, and the balance between two voices is exactly the thing a listener wants their hand on — so the slider is an equal-power crossfade in your browser, instant, and it re-renders nothing. The file you download keeps them apart, one per channel, for anyone who would rather place them themselves.
They also have to stay together, and they do not read at the same speed — jaimla is a 168 wpm model and the reference is not. Started together and left alone they are a sentence apart by the third paragraph. So it is solved twice. First the two speak the opening lines of the actual text and jaimla's pace is corrected by the measured ratio — her pace only; piper reaches rate through length alone, so her pitch, and the octave the harmony rests on, do not move. Then they are aligned where a reader already expects a breath: every sentence starts together, and inside a sentence they part company by a fraction of a second. Neither waits for the other for longer than that.
.opus and .ogg come out of the same synthesis — one set of
samples, two encoders — because a comparison where the voice could also have changed is not a
comparison of encoders. Opus was designed for speech and lands near 24 kbps here; Vorbis is quicker
to encode (about 280× realtime against Opus's 54×) and lands nearer 30. Which one you can live with
is not a thing to be told, so both are here with their byte counts, and A/B swaps between
them at the same instant rather than restarting.
Note that .opus is already Ogg — Opus inside an Ogg container — so the second file is
genuinely a different codec and not the same bytes under a different extension. That was the only
version of this comparison worth building.
In your browser — the page fetches the URL itself, parses it in an inert document with
DOMParser (no browsing context, so its scripts never run and its images never load) and
takes only text out. Nothing leaves your machine, and no markup from the fetched page ever
enters this one.
By DeltaVerse — a browser may only read another site if that site allows it, and most do not send the header that says so. When yours refuses, the fetch is made server-side instead and the status line says so, so you always know which machine went and got it.
The objection is real and it is written down in this reader's own README: a service that will retrieve any URL handed to it is an open relay into everything it can reach. That is a correct description of a naive fetcher and a specification for a careful one, so:
http and https, only ports 80 and 443, and never a URL with
credentials in it.127.0.0.1 is the same attack as typing it in the box.It does not disguise itself as a browser. A host that refuses non-browser clients is making a decision, and evading it is not a feature.
Prose that was written as prose beats prose recovered from markup — no navigation to skip, no
theme repeating itself, no heuristic about what counts as a paragraph. So a .html or
.php URL is checked for a .txt or .md sibling first, and the
sibling is preferred when there is one. One extra request, and a miss costs a 404.
Renders are kept and served as ordinary static files, so a page you have already rendered comes back instantly and costs nothing to make again. The cache holds 300 MB; past that the least recently played render is dropped first — recently used means recently listened to, not recently made, so the page everyone keeps coming back to is the one that survives.
?url= opens already reading · ?voice=mony picks a voice ·
?fresh=1 ignores the stored recording