Post by hydrophilic on Oct 8, 2015 4:50:16 GMT
What is SAM? It is a software speech synthesizer; SAM is an acronym for Software Automated Mouth. (Until recently, I thought it meant software ACTIVATED mouth...)
I remember being amazed by it on the C64, and even made a few lame "text adventures" and other fun programs on the C64.
It has been bugging me for years now that a C128 version isn't available (at least, I haven't found it).
I forget about it after awhile, until I discovered the text-to-speech synthesizer in Windows XP... it sounded almost exactly like SAM!! I forget what "name" it had ("David?")... this laptop has Windows Vista, and it doesn't have the "SAM" voice, only "Anna" (who does sound better than SAM). Also, with Windows 10 there are a couple of voices to choice from (not on that PC now, so can't elaborate).
Anyway, if you have Windows XP, tell me the text-to-speech does NOT sound like SAM!
So I had some time recently and decided to do a simple port to the C128. I analyzed the ML and found out where it was doing banking operations, made a few patches (for the C128), and tried it (in ML monitor). Well that was working, so I made a primitive BASIC interface. Then I made the silly demo program in BASIC that you can try...
The BASIC demo just BLOADs the SAM executable (ML) file into BANK 1, calls the initialize routine, then says a short sentence "Hello. I am SAM, for the Commodore 128." Next it prints a list of "character phonemes" (described later) along with example word(s) that use them. This list is mainly to help you,me,us learn the crazy phonetic system SAM uses (you can also find the original SAM documentation here).
The original SAM had a BASIC wedge that added two new commands, SAY and KNOBS. Well wedging BASIC is a bit more tricky on the C128 than the C64, so I used a more primitive method (but still easy to use). So on C64 you could do
SAY "FUN? FUN."
On the C128 (at least with this Alpha release), you have to do this
SA$="FUN? FUN." : SYSAM
The last part (SYSAM) calls SAM in machine language to speak: it requires 2 lines near the beginning of BASIC to set BANK 1 (where SAM lives) and to set variable AM equal to 39174 ($9906).So it takes a little more work in this Alpha version to use, but it does work quite well. Following are the known limitations / bugs with the Alpha version:
- No RECITER (explained below)
- No KNOBs command (you would have to use POKEs to change SAM's pitch or speed)
- Sounds like a chipmunk if using 2MHz
- Bug with error beep on PAL machines
- Wastes 40% of BANK 1 RAM (max free variables = 37.25 kiB)
For #1, you need to know that C64 SAM had an additional module called RECITER that would allow you to automatically use English plain text (well, most of the time, it isn't perfect). This version does not have RECITER, which means you have to translate the words you want spoken into SAM's phonetic language. For example, if you want SAM to say "hello" then you need something like this:
SA$="/HEH4LOH." : SYSAM
Obviously a far cry from English! It uses phonemes; in the example above: "/H" for the "h", "EH" for the "e", the number 4 to stress the first syllable, "L" for the "ll" (at least that was simple), and "OH" for "o"... also the final "." makes it sound like a sentence, no a random word in the middle of a sentence. (Try it with and without the dot to hear the difference.)
SAM's phonetic language is not easy to learn, which is why the demo lists all the phonemes with an example word (if I could think of one). Anyway adding RECITER is a big priority, but it would use more memory. I need to fix #5 so that the extra memory will be rather painless.
It needs to work friendly with FAST (2MHz) mode, so issue #3
Finally, thanks to VICE, I discovered a bug in (the original, and now this) SAM on PAL machines... whenever your string contains an invalid character(pair), SAM will not say anything but instead give you an error beep (actually, "beep beep"). One time this "beep, beep" went crazy and I used the VICE debugger and the code seemed to be working... but it just kept on beeping anyway...
Long story short: the code relies on the Jiffy Clock to increment sequentially... but on PAL systems, the Jiffy Clock will skip some values (this is so the Jiffy Clock always works, on average, at 60Hz, regardless if NTSC or PAL). So if the PAL Jiffy Clock skips the value that SAM is looking for, it goes into an almost endless loop (when I got bit by the bug, it eventually stopped, but I was panicked for a few minutes).
Oh yeah, I don't have any source code, I just took the C64 version and hacked away at with ML monitor to make it run on C128. But I do have lots of notes! I can go into detail about the inner workings if you like ( but that should probably be a separate post under Assembly Programming ?)