Classic Computer Magazine Archive CREATIVE COMPUTING VOL. 9, NO. 3 / MARCH 1983 / PAGE 272

Apple cart: a speech synthesis program. Chris Adams.

apple cart

Recently, games have started to include speech. It certainly livens up any program, and the best part about speech is that it is truly easy to do. Listing 1 is a routine that both digitizes and replays voice without any extra hardware. It is less than 128 bytes long.

I think I have succeeded in making a short yet flexible and easy to use program. So please type it in, use it, and enjoy speech in your programs.

How It Is Done

The program digitizes voice through the cassette port on the back of the Apple. You first record the word, sound, or message that you want digitized on a cassette and then play it into the cassette IN port while running the recording routine.

The program checks the status of the signal and records it in memory. Later, when you execute the play routine, the signal stored in memory is output through the internal speaker.

Using Voice In Your Program

This voice routine was designed to be easy for the beginner to use while offering significant power for the ambitious. Therefore, I have included an assembler as well as a Basic listing.

The Basic listing is in the form of data to be POKEd in memory to form a machine language program. To use it through Basic, just type in Listing 1, being careful not to make any errors. Once entered, it can be run. The last few lines of the program do a simple sum check for obvious data errors (it is possible that it won't catch all mistakes). If it passes the check sum, Voice Maker should be in memory. Before trying it, save the Basic program, and save the machine language program by typing BSAVE VOICE, A$300, L$84

Now comes the fun part. Record the message you want the Apple to digitize on tape. Actually the cassette recorder you use will make a tremendous difference in how the voice sounds. What you need is not the most expensive cassette recorder but a recorder designed for use with a computer. Of the recorders I tested, the Radio Shack CTR-80 produced the best results.

The message should start with a count down such as "3 . . . 2 . . . 1 . . . 0 . . . this is my message.' This is so you will know how to start the digitizing process.

Before you can digitize, you must set some pointers in memory for Voice Maker. The pointers indicate where to put the data in memory, how long the recording is to be, and the speed of signal samples. The speed factor is part of a delay loop. The lower the speed factor, the clearer the voice will be at playback but at the expense of memory used for the same length of message.

The speed can be POKEd at location 251 and should be in the range of 1 to 20, one being the most accurate.

For initial experimentation, use a speed factor of one. Then when you want to start using several words in a program, use a higher delay such as 10 to spare memory. The memory pointers are stored at 06 and 07. The LSB is POKEd at 6 and the MSB at 7. The LSB and MSB are found with this formula:

MSB=INT (ADDRESS/256)

:LSB@DDRESS-(MSB*256)

The next important location is the length marker. The length must be a product of 256 and is derived by adding the number of 256-byte segments to the MSB at location 7. The value derived with this method should be POKEd at location 252. The amount of memory used determines the length of the recording.

As a sample, record the message "3...2...1...0...I'm an Apple, what are you?' Put the start of the data at 24576 by POKEing memory locations 6 and 7 with the LSB and MSB:

MSB=INT (24576/256) :LSB=

24576-(MSB*256)

POKE 6LSB: POKE 7MSB

For this example use a speed of one and a length of 4K. That works out to be 16 segments of 256 bytes (each KB has four 256-byte segments). The value POKEd to 252 is MSB+ 16. Since in this case the MSB worked out to be 96, the value used is 96+16=112:

POKE 251,1 :REM SPEED

POKE 252,112 :REM LENGTH

Hook up the phone of your tape recorder to the cassette IN port in the rear of your Apple. Now as long as the Voice Maker program is properly in memory you can CALL 768. It doesn't matter if the tape has already been positioned to the beginning of the message on the tape. You can rewind and then play the tape to find the message. The first part of the program will put the signal input through the IN port directly to the builtin speaker without digitizing anything. The actual digitizing process isn't activated until you hit a key on the keyboard.

Until you do, you can adjust the volume and tone until the voice coming from the Apple is as you want it. If the volume is too low, there won't be any signal at all; if the volume is too high there will be a tremendous amount of static.

Once volume and tone are satisfactory, tory, set up the tape to begin the count-down. Listen until the zero is finished, then hit any key, and the input signal will be digitized until the allotted memory is full. While digitizing, you can't hear what is going on. When the cursor returns to the screen, the recording process is over, and you can stop the cassette recorder.

To hear the results, just type CALL 874. If all has gone well, you will have a talking Apple. If it didn't work, then there was a mistake either when you entered the data or during the experimental process.

In the future when you want a program to use voice just BLOAD VOICE and set up locations 6 and 7 with the address of the digitized data, put the same value as when you recorded into 251, and 252 should represent the length relative to the position in memory. If you want more than one recording to be used in one program, load them into non-overlapping locations, and whenever you want to use a different one re-POKE the appropriate locations.

To save a word or message, you must know how long it is in terms of bytes, as opposed to where in memory it ends. The length can be found with this formula:

L=(PEEK(252)-PEEK(7))*256

In this example, the length is 4096 and it starts at 24576 so we can type:

BSAVE MESSAGE #1A

24576, L 4096

A typical program to use this is shown in Listing 3.

10 PRINT CHR$ (4); "BLOAD VOICE'

15 PRINT CHR$ (4); "BLOAD MESSAGE #1,A 24576'

20 POKE 6,0: POKE 7,96: POKE 251,1: POKE 252,112

25 CALL 874

30 END

When you load the data, as in line 15, it is a good idea to specify where in memory you expect it to go; that is done with the phrase 24576.

If the program in which you use voice also uses strings, it will be necessary to set, HIMEM to avoid clobbering your data.

Table: Listing 1.

Table: Listing 2.