Add speech synthesis to your games with Speako8, a speech synthesis library for PICO-8 in under a thousand tokens! It's loosely based on a Klatt synthesizer and will remind some folks of Software Automatic Mouth (S.A.M.)
To add Speako8 to your games, copy and paste the library below:
Speako8's voice must be configured prior to first use:
function _init() spk8_pitch,spk8_rate,spk8_volume,spk8_quality,spk8_intonation,spk8_if0,spk8_shift,spk8_bandwidth,spk8_whisper= 140,1,1,.5,10,10,1,1,1 end |
Warning: This application may generate loud and harsh sounds. Protect your hearing! Do not test with headphones on and turn down the volume.
Variable | Range | Explanation |
---|---|---|
spk8_pitch | 60-230 | Fundamental pitch of voice (F0) in hertz |
spk8_rate | .1-2 | Standard rate of speech divisor— below 1 is slower; above 1 is faster. |
spk8_volume | .1-2 | Standard volume factor— below 1 is quieter; above 1 is louder. |
spk8_quality | .1-2 | Glottis open period— below .5 is creakier voice; .5 is modal voice; 1 is breathy voice; above 1 is weaker voice. |
spk8_intonation | 0-20 | Degree of pitch prosody in hertz— set to zero for robotic monotone. |
spk8_if0 | 0-20 | Degree to which the inherent pitch (F0) of vowels varies (in hertz)— set to zero for robotic monotone. |
spk8_shift | .8-1.2 | Factor by which to shift formant frequencies (F1, F2, F3)— above raises formant frequencies; below one lowers |
spk8_bandwidth | .5-5 | Factor by which to alter bandwidth of formant frequencies (F1, F2, F3)— below 1 narrows the bandwidth of the formants; above 1 widens. When formants are shifted upward, it is recommended to widen bandwidths as well. |
spk8_whisper | 1 or 2 | Speaking mode— Normal voice is 1; whispering is 2. |
To enable speech synthesis, you must call speako8
in the _update
function. Then call say
with a speech string:
function _update() speako8() -- must appear once unconditionally in _update. if btnp(5) then --❎ button -- use speaking if you want to check if anything is currently being said. -- if not speaking() then say("_/hh/-1.57/eh/-1.07/l/-1.33/3/ow/-1.03/-3/w/1.27/-3/er/1.65/-3/l/-1.64/-3/_/d") -- end elseif btnp(4) then -- 🅾️ button mute() --flushes the sound queue and immediately stops whatever is currently being said. end end |
Speech strings represent text phonetically and include prosody markup. The easiest way to create and test them is with the Declare web app. You can also try out different voice options with it.
If you are interested in learning more about speech synthesis, try googling these key words: Klatt synthesizer, formant, acoustic phonetics. It's a fascinating topic. An unminimized version of the library is included in the demo cart.
Special thanks to the gang on the Discord server for lending me their ears and keeping me motivated, especially @packbat, who did it for science. Thanks also to @IMLXH for finding the Klatt prosody rules.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](https://www.lexaloffle.com/bbs/files/15232/me-square.jpg)
Ah, you cannot enter in just raw english text and have it speak, @bikibird. Nonetheless - a miracle to see - pardon - HEAR - in Pico-8 !
That scary whisper would be perfect for horror games.
Gold star to the elocution expert !
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/54999/3_LogoNeu (2).jpg)
Damn! And a nice little democart. It`ll be fun to think about ways to use this. Maybe a song generator with vocals? A Spaceship-Announcement-System? Speaking NPCs in an RPG? Great work!
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/1/grappleoid_wave.png)
You had me at "Speako8", haha
Amazing work, and exciting that as it's small enough to be used as a component. Now I'm trying to find an excuse to make something that needs speech synth.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/46887/2_Screen Shot 2020-09-21 at 10.37.42 PM.png)
This is an amazing achievement, and I hope to find a project to use it in as well!
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/49583/2_HeadShot.jpg)
@dw817, I think it's possible to write phonetic and prosody rules to convert English text to speech strings and fit them into a cart, but I doubt very much that there would be many tokens left over for anything else.
@zep, yes, really looking forward to see what folks do with this. Glad you liked the name.
To everyone, thank you for your appreciations. They made my day.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/bimg/pi/pi5.png)
Imagine using this in a video game. Maybe the creepy whispers would be perfect for a scary atmosphere...
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/49583/2_HeadShot.jpg)
@idk_how_to_code, that's because it kinda is! Hawking spoke via a Klatt synthesizer and Speako8 is loosely based on that synthesizer. Much of the formant data and prosody rules I used came from Klatt's writings and are based on his own speech samples. So, yeah Speako8 sounds like Hawking sounds like Klatt.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/bimg/pi/pi16.png)
...but much worse than VOX for the ZX Spectrum. Anyway, the whisper mode is the only one i can understand. keep it up, don't remove it.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/33292/4_bubblebubble_icon.png)
Absolutely amazing. Going to try a few quotes from the original "Berzerk" arcade game.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/bimg/pi/pi14.png)
this is very cool, but what if you could feed it raw english text and let it say stuff?
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/49583/2_HeadShot.jpg)
@augusto99999, it could be done. You'd have to write rules for phoneticizing. They wouldn't be as accurate as the pronouncing dictionary that Declare uses, but they might be okay enough. You'd also have to convert the prosody rules from declare.js. I'm afraid, though, that once those tasks were done, there wouldn't be many tokens left for an actual game.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/65693/3_text.png)
gabriel is coming in your games ony for 1000 tokens of code
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](https://www.lexaloffle.com/bbs/files/12806/santo.jpg)
I've added this to my exploring game and finding the CPU/mem usage spikes crazy high when the talking happens, slowing everything else in the game down.
I guess it doesn't surprise me given the magic it's doing, but is there anything I can/should do to try and minimize the hit?
I'm just using the say() with a trigger like documented. It's an incredibly tight and well-thought out component - super thanks for that - but that puts the magic way above my head to try and tweak it :)
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/49583/2_HeadShot.jpg)
@morningtoast, As you've noticed, it tends to drop frames when the buffer is loading. You can improve things quite a bit, but not totally eliminate the issue by searching for while stat(108)<1920
and changing it to while stat(108)<256
in the Speako8 lib.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/49583/2_HeadShot.jpg)
@Vapayt, in theory, yes, but you'd have to change the pitch after each syllable and check that Speako is done saying the last syllable before sending the next.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/bimg/pi/pi5.png)
Reminds me of SAM, the software automatic mouth for the c64 iirc. It sounds pretty similar!
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/bimg/pi/pi5.png)
Very cool! It is a little robotic, but still I like it!
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/49583/2_HeadShot.jpg)
It's a lot robotic. I'm working on improving things, though. Stay tuned.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/86328/4_cort.png)
I wanted some incomprehensible babble noises in my game, and searched for "pico8 speech" in case somebody had posted a tutorial for the best way to achieve that effect with an SFX. Instead I found this library, and suddenly I knew where those last ~1000 tokens were going! The look on players' faces when the cart speaks to them is magical.
I had an idea to reduce the library's token/character count: aside from the demo cart, many applications would probably only use a subset of the library's features on a small pool of utterances. In my case, the only parameters I change from their defaults at runtime are spk8_whisper
and spk8_rate
, and only two short sentences. The remaining parameters could safely be omitted/hard-coded, and the unused phonemes could be stripped from the data tables. I don't know how much of an impact it would make in general, but towards the end of the project when I was looking for assignment statements to combine and variable names to shorten (even after minifying), every little bit would've helped.
Amazing library, thank you so much for sharing! And calling it "speako8" is just chefskiss.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/87548/arrow userpic2-4.gif)
Will this work in picotron? I've got a game I'm porting over and already have no idea if the sound even actually works yet
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/49583/2_HeadShot.jpg)
@arrowonionbelly, no I don't thinks so, not without a lot of work. Speako8 uses PCM. Currently there is no support for PCM in Picotron. I believe zep has said that PCM could be emulated by updating a waveform in the wavetable on the fly, but as far as I know there is no way to play a waveform indefinitely, so it would need to by tied to the note function or the tracker and I'm not sure how I would control for duration in that scenario.
I've played around with the FX filter for instruments in Picotron and I've been able to make some vaguely vowel-like sounds, but that's a far way from true speech synthesis.
@zep, my Picotron wish is for a biquad filter to be added as a node type with parameters frequency, Q, and gain. I believe that such a filter would allow me to build a speakophone for Picotron, which would be very cool.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/87548/arrow userpic2-4.gif)
@bikibird aww dang, that's super sad because I LOVE the way speako8 sounds and was porting my game to picotron for the extra space to include it T-T
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/99038/3_pixil-frame-0.png)
okay, thanks
Ohh, it's the coding tokens!
I really thought that was some currency XD
I do know what tokens are, sorry.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/88553/3_Screenshot 2024-01-10 17.35.19.png)
Omg i like this voice it's soo pretty... I want it to say "watch BFDI on Youtube :)"
[Please log in to post a comment]