A text-to-speech model can sound excellent and still read the wrong thing.
I ran the same short stress test through Fish Audio S2.1 Pro and Cartesia Sonic 3.5. It included coordinates, a software version, a hexadecimal error code, a synthetic password-style string, and isolated special characters.
The question was simple: when every character matters, does the model actually say what is written?
Both failed.
Fish Audio S2.1 Pro and Cartesia Sonic 3.5 reading the same test.
The failures
| Failure | Fish Audio S2.1 Pro | Cartesia Sonic 3.5 |
|---|---|---|
| Coordinate notation | Omitted “degrees” | No specific failure recorded |
2.0.1-beta | “2.0 1 beta” | “2 0.1 beta” |
0x8004210B | No specific failure recorded | Misread 0x as “zero zeight” |
P@ssw0rd_!2024 | Collapsed to roughly “password underscore 24” | Skipped “exclamation mark” |
& | Read as “and” | Read as “and” |
* | Produced an incorrect sound | Ignored it |
Fish Audio's biggest failure was the synthetic password-style string. P@ssw0rd_!2024 became roughly “password underscore 24,” removing most of the character-level information.
Cartesia handled that string better, but still skipped “exclamation mark.” It also misread the 0x prefix in the hexadecimal code and ignored the asterisk.
“No specific failure recorded” means only that this test did not document a failure for that model and item. It is not a broader pass claim.
What this actually shows
Reading & as “and” is reasonable in normal prose. It is wrong when the task is to name the literal symbol. The model needs to know whether the user wants meaning or characters.
The worse failures were omissions. Dropping an asterisk, collapsing a password-style string, or removing punctuation from a version deletes information. That matters for coordinates, software versions, serial numbers, error codes, file paths, and accessibility content.
Bottom line
Cartesia did better on the password-style string, but neither model passed the full test. Fish Audio lost more information; Cartesia still dropped a meaningful symbol and misread the hexadecimal prefix.
This does not prove either model is bad at normal narration. It proves that natural voice quality does not guarantee faithful reading of technical text.
If literal output matters, the product needs an explicit normalization mode that expands ° to “degrees,” 0x to “zero ex,” and * to “asterisk” before synthesis. Do not assume the TTS model will figure it out.
For MachinesFluent, the useful product lesson is clear: technical text should be normalized for literal reading before it reaches the voice. Model choice alone cannot protect symbols, version numbers, codes, or character-level strings.



