RSS

// SAM: Software Automatic Mouth

S.A.M. The Software Automatic Mouth

I am interested in the history of computing, and in particular the ways that early computers were used to create art and music. SAM is a fascinating example of this, and I wanted to shape a more modern version that could be used in the browser or on a low memory board like the Raspberry Pi Pico.

SAM (Software Automatic Mouth) was a text-to-speech program for the Commodore 64, published in 1982 by Don't Ask Software. Type anything, and it reads it back in that unmistakable, cracked robot voice.

This is a browser replica, built on a vanilla JS port of the original engine by Christian Schiffler, itself based on Stefan Macke's C conversion of the original 6502 assembly.

The whole engine is about 21KB minified and runs entirely in the browser, with no server-side processing or external dependencies.

Type something, adjust pitch, speed, mouth and throat, and hit Say. I have added a WAV export feature so I can use the samples in my music.

Speak

64
72
128
128
0ms

On iPhone, Safari respects the ring/mute switch for this kind of audio. If Say seems to do nothing, check it's not switched to silent.

Presets

VoiceSpeedPitchThroatMouth

To do

  • A visual mouth/waveform display while it talks, rather than just silence with a button press.
  • Save custom voice settings, not just the built-in presets.
  • Surface the reciter's phoneme output, so you can see (and tweak) how it parsed your text before it speaks.
  • Word Gap currently renders each word separately and splices in silence, which loses the sentence-level stress and pitch a single continuous phrase gets. Worth revisiting if a way to keep full-sentence prosody while still spacing out playback turns up.

Changelog

2026-07-20

  • Added a Word Gap slider (0-500ms). SAM has no native control for this, so above 0ms each word is rendered separately and rejoined with real silence in between, played back and downloaded through a custom WAV/Web Audio path rather than the library's own speak/download.
  • Fixed a click at the start of every word when Word Gap is above 0ms. Splicing separate word buffers next to silence created a hard jump in amplitude at each boundary; each word now fades in and out over ~5ms so the transition is smooth.
  • Fixed silent failures on unsupported characters. SAM's character set is plain 1982 ASCII, so smart quotes, dashes and similar copied-in characters made it fail with no feedback at all. Now it names the exact character and where it is instead of just doing nothing.
  • Downloaded files are now named "SAM_[your text]_[random].wav" instead of always "sam.wav", so repeat downloads no longer overwrite each other.
  • "°C" is now converted to "degrees celsius" before speaking, instead of tripping the unsupported-character error.
  • Fixed the mobile layout. A site-wide 240px minimum width on range sliders meant the label, slider and value could never fit on one line on a phone screen; below 768px each slider now wraps onto two lines (label and value on top, full-width slider underneath).
  • Added a fallback resume() call for the audio context on Say, since some iOS Safari versions leave it suspended even inside a tap handler.
  • Added a note that iPhone's ring/mute switch silences Say. Safari respects it for this kind of audio and there's no way for a page to override that, so it's not a bug, just worth knowing.
  • Removed the four extrapolated presets (Fast Talker, Deep Voice, Chipmunk, Drone), back down to the original six.
  • Fixed Say doing nothing on desktop Safari. The audio context's resume() call wasn't being waited for, so playback was scheduled before the context had actually left its suspended state; Safari drops audio scheduled that way with no error, Chrome and Firefox happened to tolerate it.
  • Standalone years (1000-2099) are now spelled out the way they're actually said, "nineteen eighty-two" instead of "one nine eight two". SAM has no concept of numbers at all, just digits read one at a time, so this only catches the year-shaped case rather than fixing number reading generally.
  • Fixed the "-teen" numbers (thirteen through nineteen) coming out mangled, SAM's reciter doesn't handle them correctly as one word. Split into two ("nine teen"), same fix as everything else that needs spelling out phonetically for SAM to say it right.
  • Data sizes like "21KB" and "21MB" are now spelled out as "twenty one killa bytes" and "twenty one mega bytes", both the number and the unit, instead of being read as bare characters.
  • "JS" is now spelled out as "Javascript".

2026-07-19

  • Initial release: text input, pitch/speed/mouth/throat sliders, six voice presets, Say and Download WAV.
  • Added four more presets: Fast Talker, Deep Voice, Chipmunk and Drone. Not from the original SAM docs, my own extrapolations from the existing six.

I'd love to tell you more.