~/satyajit

ssftalk: an ElevenLabs-shaped API over a formant synthesizer, benchmarked against typed-in numbers

mdjsonmcp

2026-10-19 · 17 min · speech · tts · audio · rust · benchmarks · interpretability · voice-agents

A 1:52 narrated explainer, drawn in code. Every number and picture in it is this article's own; the sources are below.

› transcript

Hi, I'm Coracle! Ssftalk says it is an ElevenLabs engine in pure Rust. Here is how it actually makes a voice. There is no neural network here. A voice is a pitch and four resonances shaping a buzz, behind ElevenLabs-shaped requests. A request arrives in the ElevenLabs format. Hand-written letter rules turn the words into phonemes. The voice is a preset: one pitch, four formants, a tilt and some breath. Even Rachel is six numbers. A synthesizer shapes a buzz with those resonances. Its source ships encrypted, so I could not read it. Four modules are not in readable form. The build script reads one encrypted file. It undoes a simple cipher whose key sits in the script. It writes out the synthesizer, recognizer, isolation and room code. Then compiles them in. Ten of the fourteen benchmark stages run that code. Here is the formula. Each benchmark stage times a loop of ssftalk calls. Then divides a number typed into the file. None of the rival tools ever runs. The audio language model saving is an amplitude gate. It marks loud samples. It counts them per frame, but an integer division shifts every frame's window. On a test second that is ninety percent silence, that gives the eighty-eight percent. Real speech gives far less. Their benchmark table. The baseline column is typed constants, so the headline compares the crate with nothing. A speedup is only real when both sides run on the same input and machine, with quality reported next to time. Six numbers. An encrypted synthesizer. Baselines typed in, not run. Every source is in the full article. I'm Coracle. Bye!

Why read this

Notabletop 60%

Reads ssftalk's code: a six-number formant voice, an encrypted synthesizer, 14 hard-coded baselines, and an 88% saving that is a rounding bug on silence.

  • Checked against the source
  • Concrete numbers to act on
  • Explained from first principles

Speech & audioRuns on a laptop CPUApache-2.0Practitioner teardown

How this was scored
Is it new?
1 of 3: An incremental tweak
Can I trust it?
3 of 3: Reproduces the headline result, or shows from primary files it is wrong
Can I run it?
1 of 3: API-only, gated or restrictive licence
Will I understand it?
2 of 3: Mechanism from first principles with figures
Can I act on it?
2 of 3: A concrete recipe, numbers or comparison
Will it last?
1 of 3: Relevant for months
Does it affect many?
1 of 3: A specialist community
Only here?
2 of 3: A teardown or measurement few others did

Score 61 of 100, ranked 305 of 577 rated articles. Each question is answered 0–3 by hand, and a 3 is rare. How articles are scored

On 18 October 2026 solidSF posted a link to solidsf-inc/ssftalk with "we will explain sometime soon… for now just go try stuff". The README calls it a "Pure-Rust ElevenLabs v1 Voice Engine, Full-Duplex Rooms & Audio-LLM Mechanistic Interpretability". Its badges say "265.5x geomean speedup (112x RT TTS)" against cloud TTS, ElevenLabs Flash v2.5, Demucs, WhisperX and a dense audio-LLM. It also sells a cloud WebSocket API, paid in "solidSF Credits" with a $10 welcome grant.

That is a lot of claim for a repository with one commit and no paper. So I did what the post said, minus the trying: I cloned it and read it. This piece explains what the engine actually is, then holds each claim against the file it points at.

Up front: I read all 31 tracked files at commit eb7722a and ported three visible functions to Python, run on our own inputs on a shared 4-core cloud VM, CPU only, on 19 October 2026. I did not build or run the crate. Its build script decrypts four source modules from a binary blob and compiles them in, and I was not going to run code nobody can read on a shared machine. Every number below is labelled measured (from the files or from my ports), reported (solidSF's figure, not re-run) or reasoned (arithmetic on the other two).

solidsf-inc/ssftalk@eb7722a · snapshot 2026-10-19
tracked files
31
license
Apache-2.0
branch
main
tests
1 file
source
287.4 kB
commit date
2026-10-18
source by language
Rust223.8 kB(17)HTML63.6 kB(2)

by size of tracked source at this commit, file counts in brackets; docs, data and vendored trees excluded

local clone, 2026-10-19 at eb7722a — branch, commit, commitDate, fileCount, hasTests, languages, license, licenseFile, shallow, testFileCount

shallow clone: counts describe the pinned tree, not the history

Repositorysolidsf-inc/ssftalk, one commit, eb7722a, 18 Oct 2026, Apache-2.0
Dependenciesserde and serde_json, nothing else (measured, Cargo.toml)
Readable Rust191,541 bytes in src/ (measured)
Encrypted Rustassets/ssftalk_moat_vault.bin, 78,428 bytes (measured), about 29% of the crate's source by size (reasoned)
Weights, model files, downloadsnone (measured: no URL, file fetch or tensor format anywhere in the code)
Paid surfacewss://api.solidsf.com/v1/ssftalk/ws, 5 to 25 micro-dollars a call (reported, cloud_ws.rs)

What a voice is here

Start with the part that decides everything else. Modern TTS, the kind ElevenLabs sells and the kind covered in speech.cpp or Paradee, is a learned model: text becomes tokens, a network predicts acoustic features or codec codes, a vocoder turns them into a waveform. The voice lives in millions of weights.

ssftalk has no weights. Its only dependencies are serde and serde_json, and nothing in the code opens a model file or a URL other than its own loopback test servers and the paid WebSocket. A voice is a VocalTractProfile in src/voices.rs: a fundamental frequency, four formant frequencies, a spectral tilt and a breathiness. Six numbers, plus a pace and a robot flag. Jesse, the house voice, is 192 Hz with formants at 540, 1680, 2680 and 3650 Hz (measured).

That is a formant synthesizer, the family behind 1980s speech chips. You make a buzzy source at the pitch F0F_0, then shape its spectrum with resonances at the formant frequencies F1…F4F_1 \dots F_4, which is roughly what a throat and mouth do to the vocal folds' pulses. Different vowels are different formant positions. The text side is rules, not a model: g2p_english in src/phonetics.rs turns letters into ARPAbet phonemes with a dozen hard-coded words ("the", "hello", "solidsf") and digraph rules for the rest.

The approach is legitimate and old: tiny, deterministic and fast, which explains the speed claims better than any kernel does. It also sets the ceiling; rule-based formant speech sounds like a speech chip. I could not hear it, because the synthesizer is in the part I could not read.

The ElevenLabs part is the API's shape

"ElevenLabs v1" here means the request and response structs and the URL paths: TtsRequest with voice_settings, previous_text, pronunciation_dictionary_locators; /v1/text-to-speech/{voice_id}/with-timestamps; the stream-input WebSocket messages with try_trigger_generation and flush. An ElevenLabs client pointed at the loopback server gets JSON of the right shape back.

It is not a reimplementation of any ElevenLabs model, and it is not a copy of an open model under that name. The built-in "Rachel", "Adam", "Antoni", "Bella" and "Josh" are formant presets that carry 20-character IDs the code labels as ElevenLabs's (Rachel is 21m00Tcm4TlvDq8ikWAM) and descriptions such as "equivalent to ElevenLabs Rachel". Rachel is 198 Hz with formants at 550, 1710, 2710 and 3690 Hz (measured). The README never says ssftalk is unaffiliated with ElevenLabs; it uses the name 24 times (measured).

Where the neural model is: the paid side

The code does name neural models, but only as cloud engines. WsEngine::Articulate150mNeural is documented in cloud_ws.rs as "Remote ARTICULATE-150M + Maya1-3B + SNAC-24kHz expressive neural speech synthesis". Maya1 is a real open model: maya-research/maya1, Apache-2.0, 3,300,928,512 parameters by the Hub's own count (measured), a Llama-style transformer that predicts SNAC codec codes, decoded by hubertsiuzdak/snac_24khz (MIT). Its card advertises inline tags like <laugh>, <sigh>, <whisper> and <chuckle> and a voice described in words, which is exactly the surface ssftalk's README sells. I found no model called Articulate-150M on the Hub.

So the reasoned reading is: locally you get a formant synthesizer behind an ElevenLabs-shaped API; the expressive neural voice, if it exists, is an open model served from solidSF's machines for credits. I cannot confirm what the server runs, since I did not call it.

solidSF infographic titled 'What to run locally for free, and what to stream over WebSocket'. Headline tiles read 265.5x geomean speedup, 24.5 ms first-audio TTFB, 88.0% audio-LLM KV tokens saved and 10 dollars of free welcome credits. A table lists four cloud engines priced in credits per call (GB300 voice conversion 25, Articulate-150M neural vocoder 15, prosody director 5, duplex room 10) and three local crate features at 0 credits, each with a speedup over a named next-best option.
The capability and pricing guide attached to the announcement post: local crate on the bottom, credit-priced cloud engines on top. All speedups on it are the publisher's (ssftalk README, assets/ssftalk-websocket-api-light.png).

The encrypted vault

Four files in src/, namely vocoder.rs, hamiltonian.rs, sts_isolate.rs and duplex.rs, are about 1.2 KB each: 5,008 bytes together (measured). Each holds a doc comment, a dispatch_over_ws function for the cloud, and one line:

include!(concat!(env!("OUT_DIR"), "/vault_vocoder.rs"));

The included file does not exist in the repository. build.rs makes it. It reads assets/ssftalk_moat_vault.bin, XORs every byte with a keystream derived from the eight ASCII bytes solidSF!, checks for the magic SSFVLT01, and writes each module it finds into the build directory, where the compiler picks it up. The key is in the build script, so this is not protection; it is obscurity, and the crate says so itself. src/hardware.rs embeds a "REVERSE-ENGINEER BOUNTY" string inviting anyone who decrypts the vault to email the author, who "wants to fly you to SF".

The licence question this raises is simple. The README says Apache-2.0, and the encrypted bytes are in an Apache-2.0 repository, but the source of the synthesizer, prosody, speech-to-speech, isolation, sound effects, transcription, alignment, dubbing and duplex rooms is not published in readable form. ElevenLabsEngine in src/elevenlabs.rs imports HarmonicIstftVocoder, ArticulateStreamer, ProsodyPredictor, build_acoustic_prior, transcribe_scribe, isolate_voice_audio, speech_to_speech and H2HSpeechJury, every one from a vault module. Ten of the 14 benchmark stages run vault code (measured). What is readable is the API layer, the voice presets, the G2P, the codecs, the "mechanistic interpretability" module and the cloud client.

The benchmark compares the crate with constants

examples/full_suite_benchmark.rs is the source of every badge. Each stage does the same thing: time a loop of ssftalk calls with Instant::now(), then push a row whose baseline is a literal.

rows.push(BenchRow {
    stage: "07. Schur-Feshbach Audio Isolation",
    ssftalk_us: iso_us,
    baseline_us: 95_000.0,
    baseline_name: "Demucs Spectral U-Net (1s)",
    ...

There are 14 of these, from 3,200.0 µs for "WebRTC SFU Turn State Machine" to 1,850,000.0 µs for "Cloud Voice Design API" (measured). No Demucs, WhisperX, WavLM, FFmpeg or ElevenLabs call exists anywhere in the repository; no file says where the constants came from. The speedup is baseline_us / ssftalk_us, and the headline is the geometric mean of the 14 ratios. From the README's own table that mean is 265.5 (reasoned; it reproduces exactly).

The comparisons are not like for like even as typed. Three examples, all measured from the example's source:

The ratios run from 1.49x (the codec, against a constant for libmp3lame) to about 85,052x (ASR), a spread of more than four orders of magnitude (reasoned). A geometric mean over that is mostly a statement about which constants were typed. Drop stages 10 and 12 and it falls to 120.7x; keep only the four stages whose code is readable and it is 149.1x; keep the three that produce or carry speech end to end (TTS, streaming, codec) and it is 3.61x (all reasoned). None of these is a speedup either, for the same reason the original is not.

The synthesis number is internally consistent: 40,833.61 µs for 4.56 s of audio is a real-time factor of 0.00895, or 112x real time (reported; the arithmetic holds). For a formant synthesizer that is plausible. It says nothing about ElevenLabs, whose 420,000 µs is a typed constant.

solidSF benchmark infographic headed 'Pure-Rust ElevenLabs v1 voice engine at 265.5x speedup'. A 14-row table lists each stage, its workload, the ssftalk time in microseconds, a 'next best option' such as Demucs or WhisperX with a baseline time, and the speedup, ending in a 265.5x geometric mean and '14 / 14 Won'.
The README's benchmark table as solidSF publishes it. The ssftalk column is a timed loop on their machine; every number in the Baseline column is a constant written into the example, not a measurement (ssftalk README, assets/ssftalk-benchmark-light.png).

"Audio-LLM mechanistic interpretability"

This is the most interesting claim to read, because all of its code is visible, in src/mechinterp.rs and src/hardware.rs. It has three parts. None involves a language model.

The 88.0% KV-cache saving

The README says ssftalk can "cut GPT-4o Realtime and Gemini Live audio KV-cache token cost by 88.0%". The function is prune_audio_llm_frames(pcm16, frame_samples, amplitude_threshold, min_active). It does this:

  1. Mark every sample whose absolute value is above the threshold (250 in the benchmark).
  2. Pack the marks into 64-bit words, 64 samples per word.
  3. For each frame, count the set bits in its words. A frame with at least 8 is "active"; every other frame is "cached".
  4. Report cached / total as token_savings_ratio.

That is an amplitude gate, a voice-activity detector of the simplest kind. It never sees an audio LLM, a token or a KV cache; the claim is that a model could skip the frames it marks. The doc comment says it finds "silent/stationary" frames; nothing in it measures stationarity.

The 88.0% comes from the benchmark's input: one second at 24 kHz, all zeros except samples 2,400 to 4,800 set to the constant 9,000. Ten per cent of the signal is a flat block and 90% is digital silence. With 480-sample frames that is 50 frames, 5 of which contain the block, so the honest answer is 90.0%.

The code returns 88.0% because of step 3. It finds a frame's words with words_per_frame = frame_samples / 64, integer division, and 480 / 64 is 7.5, which rounds down to 7. Each frame therefore reads 448 samples, and frame ff reads samples 448f448f to 448f+448448f + 448 rather than 480f480f to 480f+480480f + 480. The windows slide 32 samples further behind per frame, so by frame 10 the window has slid onto the end of the block and a sixth frame is counted active. My Python port of the function reproduces it: 6 active of 50, 0.8800; counting each frame's own samples gives 5 of 50, 0.9000 (both measured). The same slip means the last 6.7% of any input is never read at all when frames are 480 samples (reasoned: 1 − 448/480).

On real audio the number is different. I ran the same port on three of the speech clips from the speech.cpp article, resampled to 24 kHz: it marks 18.4%, 13.5% and 21.3% of frames as cacheable (measured). A conversation with long listening gaps would score higher. A quiet room does not help: one second of steady noise at an RMS of 300, about −40 dBFS, gives 0.0% (measured), because every frame has more than 8 samples over 250. Every voice pipeline has a gate like this. It is not a result about GPT-4o.

The 1-bit SAE circuit matcher

A sparse autoencoder, in interpretability work, is trained on a network's activations to split them into a dictionary of sparse, readable features. Matching binarized codes with XOR and popcount is a real speed trick.

SaeVoiceCircuitMatcher does the matching half: for each 256-bit query it finds the dictionary entry with the smallest Hamming distance, four u64 XORs and popcounts per pair, in plain Rust (the "Tensor-Core b1.xor.popc" name refers to PTX that the code says runs only on the paid cloud). There is no autoencoder. In the benchmark the dictionary is 256 entries whose bits are four hash constants multiplied by the entry's index plus a small offset, and the 16 queries are the dictionary's own first 16 entries (measured). Each query finds itself at distance 0. No activations from any model are ever produced to encode.

The 64-D "glass-box" voice signature

GlassBoxVoiceSignature64D::from_audio computes a 64-element vector. Some coordinates are honest features: the fraction of samples with each amplitude bit set, the zero-crossing rate, RMS, peak, an autocorrelation pitch estimate, a 24-segment loudness envelope. Others are not features of the audio at all. Coordinates 24, 25 and 26 are the constants 0.875, 0.75 and 0.9375; coordinate 32 is 1.0; coordinate 33 is 15/24; coordinates 13 to 15 are bits of a running hash of the samples (all measured). The benchmark's verification is "self-cos=1.000000", the cosine similarity of the vector with itself, which is 1 for every non-zero vector.

The "counterfactual ablation" API is a config flag read by the vault's synthesizer: zero some harmonics, drop breath noise. Mechanistic interpretability asks what a trained network learned; here someone wrote the rules, so there is nothing to discover.

Voice cloning without formants

The README's clone row says "64-D Glass-Box F0F_0 + 4-formant tract extraction" in 305 µs. add_cloned_voice in src/voices.rs measures F0F_0 by autocorrelation on one window of at most 2,048 samples (85 ms at 24 kHz), clamps it to 85 to 310 Hz, and then sets the formants to a fixed template scaled by pitch:

Fk=Tk⋅min⁡ ⁣(max⁡((F0/165)0.35, 0.82), 1.22),T=(500, 1550, 2550, 3500) HzF_k = T_k \cdot \min\!\big(\max\big((F_0/165)^{0.35},\ 0.82\big),\ 1.22\big), \qquad T = (500,\ 1550,\ 2550,\ 3500)\ \text{Hz}

Formants are never measured from the reference audio (measured). Breathiness is one minus the autocorrelation peak. So two speakers with the same pitch clone to the same voice. "Voice design" is the same idea from text: tract_from_description picks 120 Hz if the description says "male" or "baritone" and 195 Hz otherwise, nudged by words like "deep" or "bright" (measured).

The 1,572x against ECAPA-TDNN compares this with a constant for a neural speaker encoder. The two do different jobs: ECAPA produces an embedding that tells speakers apart; this produces a pitch.

Two output formats that are not what they say

MP3. OutputFormat::Mp3_44100_128 is ElevenLabs's default output format, so a drop-in client will ask for it. ssftalk's encoder writes the four bytes FF FB 90 64, which is an MPEG-1 Layer III frame header, then the ASCII tag SSFM, a length, and a j128 payload (measured, encode_audio_output in src/codec.rs). There are no MP3 frames after the header. A browser, ffmpeg or any MP3 decoder will reject the file or play noise. ssftalk's own decoder reads it back, which is all its tests check. That alone breaks "100% API parity" for the most common request.

j128. This one holds. j128 is a block ADPCM codec, and a careful little one. Each block is 15 samples, 0.625 ms at 24 kHz: two bytes for the first sample verbatim, one header byte with a 2-bit predictor choice (zero, previous sample, linear extrapolation, mean of two) and a 6-bit index into a 64-entry scale table, then 14 four-bit residuals. The encoder tries all four predictors and three neighbouring scales and keeps the one with the least squared error. Fifteen samples in ten bytes is 1,600 blocks a second, exactly 16,000 B/s or 128 kbps, a third of 16-bit PCM (measured).

The code comment claims "> 28 dB speech SNR". My Python port of the encoder and decoder, on the first 4 s of three speech clips, gives 39.9, 30.9 and 38.0 dB (measured). That clears the claim. It is still a 128 kbps waveform coder for 24 kHz mono speech; Opus carries the same speech well at 32 kbps, which is what this site uses for audio. Its "1.5x faster than FFmpeg libmp3lame" is, again, a ratio against a constant.

The cloud client

SsfTalkWsClient::connect takes wss://api.solidsf.com/v1/ssftalk/ws, strips the wss:// prefix, and calls TcpStream::connect("api.solidsf.com") (measured). Two things follow, both reasoned from the code rather than from a connection I did not make. The address has no port, which Rust's socket parser rejects, so the default URL fails before any packet is sent. And wss means WebSocket over TLS, but a crate whose only dependencies are serde and serde_json has no TLS: given a host and port, it would send the HTTP upgrade, including Authorization: Bearer <your key>, in clear text.

Every cloud test in the repository talks to SsfTalkLoopbackWsServer, a local mock in the same file that answers with a hard-coded server_exec_us: 28.4 and debits a balance it keeps in memory. The GPU kernels the README lists for GB300 and Apple Metal are three placeholder strings, for example "/* [solidSF CLOUD_WS VAULT: rosenberg_harmonic_istft + symplectic_cfm dispatched via wss://api.solidsf.com/v1/ssftalk/ws] */" (measured). In the same X thread solidSF wrote that the work is "coming to apple metal shortly", while the README's benchmark header names "Apple Silicon Unified Memory (aarch64 NEON + Metal 3.1)". The second announcement post quotes a different product, solidcv, "12.1x faster than opencv", which is not in this repository.

The ledger

Every claim above, in one place. Filter by verdict.

What holds, and what to take from it

Some things here are real. The ElevenLabs-shaped types are a reasonable layer to put in front of any local engine. The j128 codec meets its own SNR claim. Truncating an agent's transcript at the character where the human interrupted ("heard characters") is the right idea for voice agents. And a deterministic formant synthesizer is fine to ship if you call it that; earshot is classic DSP presented honestly.

The rest is vocabulary. "Mechanistic interpretability", "sparse autoencoder", "KV cache", "Tensor Core" and "twelve theorems" name, in the code, an amplitude gate, a Hamming search, a hash, a struct and comments. The speedups divide a timed loop by a number someone typed. The parts that would show whether the voice is any good, the synthesizer and the recognizer, are the parts you cannot read.

Testing "faster than WhisperX" means running both on the same audio and machine and reporting word error rate next to the time, as in Whistle and VoiceStudio. Until solidSF publishes the explanation the post promised, nothing in this repository shows the numbers on its badges.

What I could not check

Cite this article

For attribution, please use the following reference or BibTeX:

Satyajit Ghana, "ssftalk: an ElevenLabs-shaped API over a formant synthesizer, benchmarked against typed-in numbers", ai.thesatyajit.com, October 2026.

bibtex
@misc{ghana2026ssftalk,
  author = {Satyajit Ghana},
  title  = {ssftalk: an ElevenLabs-shaped API over a formant synthesizer, benchmarked against typed-in numbers},
  url    = {https://ai.thesatyajit.com/articles/ssftalk},
  year   = {2026}
}
share