Most adaptive systems restrict the user to the text that is currently on the screen. This makes sense for screen oriented applications such as emacs or lynx. However, other applications, such as the standard Unix shell, present a command-response interface. Under these circumstances, an ongoing log of the interactive session is more appropriate. The user can review each line of text, exactly as it was typed (input) or generated (output). Jupiter allows the user to run in linear or screen mode.
This audio feedback isn't much help in screen mode. In fact you might tire of the clicks and chirps as the screen is constantly being refreshed. However, it is a simple matter to turn it off when running in screen mode, and reenable it for line mode.
Those wishing to incorporate console audio feedback into their own adaptive software can use my clicktty module, which is included in this package. This module generates audio feedback as text is generated, but it assumes some other process, such as Emacsspeak or Brltty, is actually reading the words.
^N eline for eline for read
will cause control-N to advance to the end of the line, move forward one space (onto the next line), advance to the end of that line, forward one space, and start reading. In other words, ^N skips down two lines and begins reading. In screen mode, composite commands might locate the visual cursor and read the character, word, or line that is indicated by the cursor. In a more contrived, yet not implausible example, suppose you often read the second to last column in a spreadsheet, and you'd like a single keystroke command to do this.
eline lspc back sword lspc back word
might work, if the entries in your spreadsheet are simple enough. Other composites let you move up and down this all-important column, or switch between this column and the first column (the customer's name). You can usually create whatever commands you need in your work, and bind them to single keystrokes.
If you download this package from the internet, and manage to install it yourself, I'd still like to know that you are using it. That way I can keep you informed of bug fixes and new features etc. Please drop me a line.
Most of the atomic commands refer to a cursor. This is the reading cursor, which should not be confused with the visual cursor on the screen. The reading cursor roams around the text, and corresponds to the text being spoken by the synthesizer at the time.
In screen review mode, the cursor (i.e. the reading cursor) moves about in screen memory. If you move up one row, the cursor literally moves up one row on the screen. thus each line of text is actually one line on the screen, 80 characters long, followed by a virtual newline character. There are 25 of these "lines" in the buffer, corresponding to the lines on a display screen. That is the text you are allowed to read. Even in screen review mode, the reading cursor and the visual cursor are not the same, although the former can "sync up" with the latter, at your command.
In line mode, the cursor travels through a log of your interactive session. Each line is as you typed it (input), or as it was generated (output). You can review text that has scrolled off the screen long ago. The size of the circular buffer is a compile time constant, and can be increased if you wish. However, a text buffer is allocated for each open virtual terminal, and /etc/inittab opens six just for starters, so watch your memory consumption.
Each command has a short, somewhat cryptic name. The names are presented below, and should be used in the configuration file that builds and binds composites. Although the names are short, they do follow a pattern, and it's better than giving each command a number. 8-)
The words used to read punctuation marks are under the user's control, as indicated by the configuration file. I recommend short words, such as "dot", rather than "period".
alpha hotel oscar uniform
bravo india papa victor
charlie juliet quebec wiskey
delta kilo romeo x-ray
echo lima sierra yankee
foxtrot mike tango zulu
golf november
For example, to enable/disable console noises, activate the toggle function, then hit 'n'. Jupiter produces the high active tone if the mode is enabled, and the low inactive tone if the mode is disabled. When sounds are disabled, the inactive tone will be the last sound you hear, until you enable audio feedback again. These on-off tones are not generated unless the toggle command is the last in its composite.
clmode 1 eline for read
In contrast, if you need to go back one line, you probably don't want to read the rest of the screen. You need to listen to that line carefully, and perhaps the line before. An appropriate composite would set one-line reading mode, back up to the previous line, and start reading. Recall that the mode changes don't generate any sounds when they are part of a larger composite. All you hear is the line you want to hear.
Due to roundoff errors, the pitch of a predefined voice may not match any of the 10 preset pitch levels used by Jupiter. Thus incrementing and then decrementing the pitch may not return the unit to the exact same frequency. Of course, once you have issued a pitch command, you will remain on Jupiter's 10 pitch levels, until you switch voices again, or reinitialize the unit.
A new definition overwrites the old one, and if there is no replacement text, the old definition disappears. If you add too many replacements to the word replacement table, which is currently 30K, you will hear the boundary error tones.
Jupiter understands simple English suffixes, and the rules for applying them. In the above example, we turned "read" into "reed". This effectively maps "reading" into "reeding", and "reads" into "reeds". Most of the time this is what you want. When it isn't, you can ad special translations for the conjugate forms of the root word.
^Xcontrol x@Xalt xF7function key 7+F7shift function key 7^F7control function key 7@F7alt function key 7#7numpad key 7, without numlock+#7shift numpad key 7^#7control numpad key 7@#7alt numpad key 7#.numpad key . (following the + ^ @ convention)#+numpad key +#-numpad key -#*numpad key *#/numpad key /upup arrow (down left and right are similar)
To illustrate, suppose you want control j to read the previous word. You would type
^J sword lspc back word
The configuration file, presented in the next section, contains a wealth of examples.
In this version, composite commands are somewhat limited. If an atomic command speaks, or initiates reading, it must end the composite. You cannot construct one composite that reads the current word and the next word. Also, commands that require follow-on strings, such as this bind command, must appear at the end of a composite. If a command requires a follow-on character, such as toggle, the caracter can be included in the composite, provided it is an alphanumeric. Thus a single keystroke can toggle audio feedback or single-line reading. I have placed both these composites on prominent functions keys, because I constantly toggle these modes in my work.
After activating this command, enter the key designator, as described above, followed by the less than character '<'. Then type the replacement text, followed by the return key. You cannot embed the return key or the escape key directly into a macro, as these terminate follow-on input. However, \nnn is translated into its octal equivalent, so that \15 becomes return and \33 becomes escape. In addition, \b \f \t \n and \r are translated as they would be in a C string. Thus it is easy to build a macro that contains control characters, including the all important return key \r.
The configuration file, /etc/jupiter.cfg by convention, is line oriented. Lines beginning with a semi colon are ignored. I would have used the # sign, like shell scripts, but the keys on the numeric keypad are denoted #1 through #9, when specifying key bindings, and that implies a leading #. So I decided to use the semi colon, which is a standard comment character in many assemblers.
Each non-comment line establishes a pronunciation, binds a speech command, or defines a macro. The text is written exactly as it would be typed in by the user, after invoking the corresponding atomic command, as documented in the previous section. For instance, a line in the configuration file contains the text "read reed", and this establishes the pronunciation of the word "read". Since examples are the best form of documentation, I'll stop here and let you peruse two sample configuration files. The first arranges the keys in a manner that will be familiar to anyone who has used ASAP (DOS) or Speakup (Linux). You'll know exactly where the reading keys are and what they do. This makes it easy to jump right into Jupiter without a steep learning curve. The second is my config file, which uses more control keys, so that I don't have to move my hands all over the keyboard just to read the current word/line etc. I have swapped the control and caps lock on my system, making it much easier to activate the control keys. This also prevents me from hitting caps lock by mistake.
The last line of the config file is often the "invoke now" line,
as indicated by a leading ^^.
For instance,
^^ voice 7 pitch 3 speed 8 stmode s
establishes the voice parameters and puts you in screen review mode.
This puts Jupiter in a known state for you,
so you don't have to write a separate shell script with strange looking echo commands.
The talking Linux kernel does not actually read /etc/jupiter.cfg and configure itself; another utility is involved. The program "talkcfg" reads the configuration file and passes it to the Jupiter module inside the running kernel. This is similar to the loadkeys(8) utility, which passes a keymap to the running kernel. Thus Jupiter can be reconfigured at any time; no need to reload the module. You may want to place the command
post-install jupiter talkcfg /etc/jupiter.cfg
in your /etc/modules.conf file. Thus, whenever modprobe loads the jupiter speech module, it runs the talkcfg utility, which configures the system.
The talkcfg utility is startlingly simple. It reads each line in the configuration file, prepends the appropriate escape sequence, and sends the modified string to standard out. That's it! The machinery inside Jupiter spots the escape sequence and activates the corresponding atomic command, which swallows the follow-on string and parses it, as though it had been typed in at the keyboard. That is why the syntax is, and must be, exactly the same as if you had typed it in yourself.
The talkcfg program can be run in test mode, by using the -t option. This verifies the syntax of your configuration file without affecting the running system. If there are syntax errors in your file, and you send it on to the kernel anyways, Jupiter will beep once for every improper line. This is not a serious problem -- just fix the file and run it through again.
The markl and markr commands mark the left and right boundaries of a block of text to be copied. The left boundary must be specified first, then the right. All text between the two markers, inclusive, is captured in an internal buffer. The markers can span multiple lines. Line breaks are stored as linefeed, ascii 10. This is Linux for newline. The running application will think you are hitting return after every line, as though you had typed it in at the keyboard.
There is a limit to the amount of text that can be captured in this way, so don't get carried away. At present the limit is about 200 characters, the size of a tty input queue. If you need to manage large blocks of text from your interactive session, use the /proc/accessibility/jupiter/buf* files, described in a later section.
The captured text is stored as a macro, and bound to one of your alt keys. The markr command requires a follow-on letter, a through z. If you follow up with k, the captured text is reproduced by hitting alt-k. This holds true even if you switch consoles. Cut and paste is truely a global feature.
Let's consider some examples. Suppose you want a single keystroke, f7, to capture the current line of text, at the reading cursor, and make it available as a macro under alt-k. The following composite should do the trick. The back command prevents the final line break from becoming part of your macro.
f7 sline markl eline back markr k
For another example, let's say you are working in screen mode, and you don't want all the trailing spaces at the end of a line on the screen. Also, you are capturing a line that you typed in at the shell, rather than a line of output. Thus you don't want the leading dollar prompt. We skip two spaces over to bypass the prompt.
f7 sline for for markl eline lspc back markr k
When marking text, you may want a key that moves to the beginning of the current word and then sets the left marker. Rarely will you want to copy part of a word, so you may as well move to the start. Thus most people will use "sword markl" for their left mark command. Some will also establish a "sline markl" command to mark the beginning of the current line. It all depends on the type of text you normally cut and paste.
I wrote a general purpose self-talking wrapper, called speaknow, which I can then use to make any shell command self-talking. It moves the reading cursor to the end of the buffer, runs the designated command, and then starts reading. Thus `speaknow echo hello world' will cause the computer to print hello world on the screen, and then read it. You don't have to hit any function keys at all.
# Self-talking programs
function speaknow() {
if [ -t 1 ] # terminal
then echo -en "\33{ebuf"
fi
"$@"
if [ -t 1 ] # terminal
then echo -en "\33{for\33{read"
fi
}
# Check current directory, date, and time -- self-talking.
alias pwd="speaknow /bin/pwd"
alias cdate="speaknow /bin/date +'%B %-d'"
alias ctime="speaknow /bin/date +'%H:%M'"
Note that this speaknow function tests for an interactive terminal. Thus you can redirect pwd into a file, and get only the current directory. Run pwd interactively and you'll also get the escape sequences needed to read the output.
Most screen oriented applications, such as emacs, produce escape sequences of their own, compatible with the VT100 terminal interface. These sequences, which begin with "\33[", rather than "\33{", modify the color and highlighting of text fields, and manage the visual cursor on the screen. Although these escape codes are entrained in the standard output, it doesn't make much sense to dump them into the text buffer. Therefore, Jupiter passes them directly through to the console. This leaves only the text output in the buffer, which the blind user can read, and in some cases, make sense of. Escape codes that specifically reposition the cursor cause a newline to be placed in the buffer. This separates text fields within the buffer; else they would all run together into one big word. All of this is moot if the blind user chooses to access his screen oriented program in screen mode; but if he wants to run it in line mode, or review his interactive session later on, Jupiter tries to "do the right thing".
These two features, escape braces and escape brackets, can be disabled by "clmode b" and "clmode B" respectively. This is generally not done, except for debugging the system.
The startup sound tells you that Jupiter is up and running, even if your synthesizer's connection isn't working, and you can't read any words. In fact, you will be amazed how much you can get done without any speech -- acting only on the audio feedback at the console. You know the sounds of the common messages, standard and anomolous, hence you proceed accordingly. You can log-in successfully, issue a few simple commands, run sync (so your file system is safe), and try to reinitialize your synthesizer on its designated serial port (in case autoprobe failed). If this doesn't work, you can always reboot, and ask lilo to launch a backup kernel.
Since control keys are so important, and the caps lock is so annoying, most users will want to swap them. Thus the control key is just to the left of the a key, a much more convenient location. This can be done by running loadkeys on the following file.
# Swap caps-lock and control
keymaps 0-2,4-6,8-9,12
keycode 58 = Control
keycode 29 = Caps_Lock
keycode 97 = Caps_Lock
Suppose you are reading the Declaration of Independence, and you have just heard the words "We hold these truths to be self-evident." The phone rings, and you hit the shut-up key. Where is the reading cursor? It may be several phrases ahead, perhaps all the way down to "life, liberty, and the pursuit of happiness." Speech latency is the distance, measured in words or in seconds, between the speech you are hearing and the location of the reading cursor. If we send an entire sentence to the synthesizer, and receive no feedback until that sentence is spoken in its entirety, the latency could be large. The better synthesizers provide real-time feedback as each word is spoken, so the reading cursor can follow along. Doubletalk provides this feedback, hence Jupiter can transmit an entire sentence for best pronunciation, and still track the speech with its reading cursor. This is not possible in generic mode.
Short numbers, four digits or less, are read naturally, rather than digit by digit.
Thus 12 becomes twelve, 338 becomes three thirty eight
or three hundred thirty eight (depending on context),
1492 becomes fourteen ninety two,
2nd becomes second, and 104th becomes one hundred fourth.
This translation is not done if the number begins with a zero.
Multi-token numbers such as 12,345 are also translated,
up to six digits with literal mode on, and 15 digits with literal mode off.
This is one of many tradeoffs between clear English speech and accurate unambiguous information.
In the C language, you might encounter an array of initializers
{102,305,907,484}.
We wouldn't want to read this as a number in the billions.
Since C programmers always work with literal mode enabled,
they will hear each 3 digit initializer, separated by commas.
On the other hand, 1,000 is probably one thousand, even in a C program
(perhaps a comment or print statement), so we read it that way.
We make statistical choices and hope we are right most of the time.
When a token consists of numbers and letters, Jupiter first separates the token into its components, such that each piece contains either letters or numbers, but not both. Numeric pieces are read as described above. Letter components are then split at case boundaries. This is especially useful for programmers who must deal with runTogetherVariableNames in their work. Once a letter component is isolated, Jupiter compares it to the items in the replacement table, as set by the configuration file. If the user has respelled this word, the new text is sent to the synthesizer. If the word is not found, Jupiter tries to strip off the suffix and respell the root word. This was described in the atomic command setpro. If the replacement text contains spaces or digits, the substitution is not made, because Jupiter isn't sure how to put the original suffix back on. If the word was not respelled by the user, Jupiter asks whether it is an English word, or whether it should be read letter by letter, as in xyz. This software is not trivial, and will not be described in detail. Needless to say, it sometimes makes mistakes, so don't be afraid to establish your own spellings in your configuration file. Words longer than six letters are never read letter by letter. It may not be an English word, but you don't really want to hear all those letters either. A word that looks like a name, with a leading capital letter, is pronounced, unless it contains no vowels.
The Jupiter system includes a sophisticated text preprocessor that reformats words and numbers, as described above. This preprocessor also translates dates, times, units, state abbreviations, and much more. Some of these transformations occur all the time; others are suppressed when literal mode is active. This preprocessor is well encapsulated, and can be linked into any adaptive speech package. It can also be incorporated into a stand-alone speech application such as an email reader. The details of this text -> TTS preprocessor are presented in another document.
At first you might anticipate a new atomic command (svbuf), which expects a follow-on string (the filename), and then saves the text to that file. A Linux expert could probably implement this, but I cannot. In fact I couldn't even do it in DOS. The problem is, keystroke commands are processed at interrupt level, and there are only certain things an interrupt handler can do, in DOS or in Linux. A handler can write to the serial port (thus talking to the synthesizer), because it "owns" that serial port, but it cannot write to a disk file, while (perhaps) other processes are in the middle of writing to that disk. The race conditions are unmanageable. One might set a flag and let a daemon within the kernel, or a daemon process, write the file a millisecond later, when the kernel is back in system/process mode, but this is just beyond me.
You might anticipate another approach, which Jupiter used when it ran under DOS. We could greate a new ioctl call that returns the text buffer, or at least makes it available to the running program. Since ioctl runs at system level, rather than interrupt level, this does not pose a technical challenge. In fact, Speakup has lots of new ioctl calls. However, this approach poses a serious administrative challenge when there are multiple independent developers. What's to keep me from accidentally reusing the same ioctl numbers as someone else? Nobody could have Speakup and Jupiter on the same machine. Even if there are no collisions, adding new #defines to the system ioctl.h header file forces an entire rebuild of the kernel, and requires extensive documentation. It is not self-evident that ioctl(0, 2739, &mybuf) fetches a copy of the text buffer.
Fortunately Linux has a better, I might even say brilliant, approach, namely the /proc file system. This directory looks like it has files under it, but they are really dynamic aspects of the system. For instance, there's a file for memory layout, another for interrupts, another for dma, another for allocated IO ports, another for each running process, and so on. Furthermore, modules and device drivers often create their own files under /proc, telling the user all about that device or module. Note that these files are plain ASCII, and are (generally) easy to read and understand. They are almost self-evident, requiring little or no documentation. Whenever somebody wants to pass new information back to the user from the kernel, he doesn't have to invent a new system call. Instead, he simply stuffs a new file under the /proc directory, which the user can read, and in some cases write to. This is a natural approach for Jupiter.
If you are on console 1, also known as tty1, and you want to save the buffer into foo, you would type `cp /proc/accessibility/jupiter/buf1 foo'. The other text buffers, corresponding to the other consoles, are in buf2 through buf6. Returns, which act as line breaks in the buffer, are automatically converted into linefeeds, the standard Unix line delimiters.
One thing you don't want to do, if you're on tty1, is type `cat /proc/accessibility/jupiter/buf1'. The beginning of buffer 1 is printed out onto the screen, whence it is appended to the end of buffer one. When cat gets to what was formerly the end of the buffer, there is more stuff to print. The snake chases its tail forever. Hit control c to break out of this loop.
Note that other adaptive modules can put other subdirectories in /proc/accessibility, consistent with my open architecture. Each adapter can do what it likes.
Now for the bad news; the files /proc/accessibility/jupiter/buf* can only be read by root. If they were readable by all, you would have no security or privacy. Someone could read your log and see, in plain text, the password you sent to your ftp server, etc. You will need to switch to a root console to save your session. I often leave console 6 up as root, to do privileged tasks. And I'm never in console 6 unless i have to do something as root. So you might hit alt-f6 to switch to root, run the save command, then hit alt-f1 to return to your work. Alternatively, you can right a setuid root program to save your buffer. (Consult the author if you're not sure how to do this.)
Of course, most blind users own and monopolize their own PC, and are more interested in convenience than security. If you fit this category, you will want to own the files under /proc/accessibility/jupiter, so you can read them any time you want without having to become root. This is accomplished by a module parameter. If your user id is 300, as shown by `id -u', you can pass owner=300 to Jupiter when it is launched, and all the files under /proc/accessibility/jupiter will be yours. Note that this approach still provides good security in a multi-user system, as well as convenience for you. Module parameters will be discussed in a later section.
dd if=fdboot.img of=/dev/fd0 bs=1k
# change floppies - no mounts or unmounts required.
dd if=fdramdisk.img of=/dev/fd0 bs=1k
When you have made the floppies, insert the first one and reboot the computer. You may hear a bell as the machine restarts - it depends on your machine. Then you should hear a double bell at the lilo prompt. I always embed two control g's in my boot message. At this point you must type r and hit return, for rescue floppy. The disk will spin as the kernel loads. When the first disk stops spinning, put in the second and hit return. Once that floppy is read, you must enter your symthesizer, port, and preferred keyboard. This is how the screen looks at this point.
I'm ready to load the Jupiter speech adapter, but I need to know the synthesizer and port. Enter synthesizer, port, and keyboard layout, space separated, on one line. Synth codes are: dti (DecTalk internal), dte (DecTalk external), dbe (DoubleTalk external), epc (Echo PC), bns (Braille N speak), and g (generic). Port is a number from 0 to 3. Include this number even if the synth is internal; it selects an io base address. Finally, enter k for Karl's keyboard or s for the Speakup layout. Example: dbe 0 s (DoubleTalk external on port 0 with Speakup keyboard)
Enter the codes as described above. If you're using BNS, be sure to put the unit in "block shaking" "line" mode. You have to do this from the keyboard; I can't configure it from my end.
Function keys and control keys should now activate speech. If you weren't sure of the port, you can try another port using the alt-r key. Follow alt-r with 0 through 3, for a different port. This resets the synthesizer on port 0 through 3.
If you're still not hearing words, or you only get one word every few seconds, type alt-o. This overrides the DSR and CTS signals. If the synthesizer is unknown to me, I'm probably not interpreting these signals correctly in any case.
Sorry, but the Dectalk PC cannot be accessed from floppies; there is no room for its firmware. You'll need to use the talking CD. In fact, you may need to boot from the CD in any case, since some computers don't even have floppy drives. Download the compressed CD image (about 30MB), uncompress, burn the image to a writable CD, and boot from that CD. But before you do, read the documentation on the talking CD.
In either the rescue floppy or the CD, there are a number of predefined mount points under /mnt. List the directory and you'll see what I mean. These are pretty self-explanatory. Type `mount /mnt/a1' to mount the first partition of drive 1 on /mnt/a1. Mount /mnt/b2 for the second partition of drive 2, and so on. /mnt/fd is the floppy drive, and /mnt/cd is the CD rom. You don't have to specify the file system type; we figure it out automatically. You can look at Linux files (ext2 or ext3), Windows, or DOS.
You must unmount these file systems when your done, or they may be corrupt. Cat /proc/mounts to see what is mounted.
If you have mounted a working Linux partition, you can chroot into that partition and go to work, as though you had booted straight in. If /mnt/a1 is a working Linux partition, type `chroot /mnt/a1', do your work, then exit, and you'll be return to the rescue CD. Note, you will not be able to mount /proc inside your Linux partition, and lots of programs, like ps, won't work without /proc. If you're going to be working inside a partition for a while, and you want access to all your favorite utilities, you should probably unmount /proc and /dev/pts first, then chroot to your partition, then remount them there. But you have to keep track. You have to unmount these virtual file systems before you exit back to your rescue disk.
When you're done with your rescue session, be sure all file systems are unmounted, then you can turn off your computer, or hit the reset button on the front panel. Make sure all rescue diskcs, or other disks, are removed before you push the button, or the computer will try to boot off your floppy again.
Begin by downloading the package, which is a compressed tar archive. When unpacked, it creates a jupiter directory and populates it with this user's guide, several support files, and two patch files. The first patch, kernel-version.patch, modifies several functions in the keyboard and console device drivers. In this context, version is 2.2.16 or 2.4.4, for 2.2 kernels and 2.4 kernels respectively. select the appropriate one for your 2.2 series or 2.4 series kernel. The modified device drivers call Jupiter routines, which intersept keyboard input and console output. This patch also creates the accessibility directory, next to the sound directory, beneath drivers. I am trying to follow the sound card paradigm. Various sound card drivers are implemented as modules and plugged into one universal sound receptacle in the kernel. Similarly, many adaptive modules, within the accessibility directory, will all plug into the modified kernel. Use kernel-version.patch to "prepare" the kernel for adaptive modules.
The second patch, jupiter-version.patch, places the Jupiter speech system in a jupiter directory beneath the accessibility directory. This holds the source for the Jupiter speech package. Move to /usr/src/linux, apply both patches, rebuild the kernel and the modules, install the kernel, adjust lilo.conf, run lilo, reboot, and activate the Jupiter module. If you unpack Jupiter in your home directory, the following script should build the software. Remember that it must be run as root.
cd /home/your_login
# We assume the downloaded archive jupiter.tar.gz is here
tar xzf jupiter.tar.gz
rm jupiter.tar.gz # it's unpacked, don't need the tar file any more
package=/home/your_login/jupiter # contains all the files
cd $package
cp talkcfg /usr/bin
cp jup_*.cfg /etc
ln -s /etc/jup_kad.cfg /etc/jupiter.cfg
lsrc=/usr/src/linux # Linux source code
cd $lsrc
patch -b -p0 <$package/kernel-version.patch # apply patch to the kernel
patch -b -p0 <$package/jupiter-version.patch # bring in Jupiter speech adapter
make config
# Say yes when it asks about CONFIG_ACCESSIBILITY
# and say M for CONFIG_JUPITER
# You can just hit return for all other questions.
make dep
make bzImage
cp $lsrc/arch/i386/boot/bzImage /boot/jrlinux # jupiter ready linux
make modules
cp $lsrc/drivers/accessibility/jupiter/jupiter.o /lib/modules/*/misc
depmod -a
If patch cannot update a source file, you should contact the author. The compilations may produce a few warnings, but there should be no fatal errors. If all goes well, you will have a Jupiter-ready kernel in /boot/jrlinux. Edit the file /etc/lilo.conf and add a new block that looks something like this.
image=/boot/jrlinux
label=jr
root=/dev/hda1
If you have some other root, such as root=/dev/hda5, you will want to use that. You may also want to edit /boot/message, so that it says something like, "Type Linux or wait 5 seconds for the original kernel; or type jr for the Jupiter-ready kernel." Include a control g bell in this file, so you will "hear" the lilo prompt. Run lilo, and if there are no errors, reboot the computer. Type jr at the lilo prompt to launch the modified kernel. This kernel does not talk; it is simply ready for talking modules. It should do exactly what the old kernel did. You won't notice any difference. At this point you could install Jupiter using insmod, with the parameters (e.g. synthesizer and com port) on the command line, or you could use the modprobe facility.
alias access jupiter
options jupiter synth=double-lt port=0 baud=9600 lang=e owner=300
post-install jupiter talkcfg /etc/jupiter.cfg
The first parameter on the options line is the name of the synthesizer. At present Jupiter recognizes epc (echo pc), dti (Dectalk internal), dte (Dectalk external), dbe(Doubletalk external), bns (Braille N Speak), and g (generic). If the designated synthesizer is not recognized or supported, generic is the default. Keep in mind, generic works with most external synthesizers.
The baud= parameter sets the baud rate for an external synthesizer. The default is 9600. Only the "standard" baud rates are supported.
The port= parameter sets the serial port. Valid ports are 0 through 3, following the /dev/ttyS? convention. Dos users can simply subtract 1 from the com port number. If there is no port parameter, Jupiter will autoprobe for the device. Keep in mind, Jupiter cannot autoprobe for a generic synthesizer. Note that the serial port is always polled, saving that precious IRQ for the sibling serial port.
The owner parameter establishes the owner of the files under /proc/accessibility/jupiter. These files convey the status of the running adapter. Recall that buf1 through buf6 hold the text buffers corresponding to the 6 virtual consoles. You will usually set owner to your user id, so that you can own these files.
The lang=e parameter specifies English. Other languages are not supported at this time, although I am working on a Spanish version, and any help in this area would be greatly appreciated.
Add these fields to the insmod command line, orun `modprobe access', and Jupiter should be installed with your parameters. If you're using modprobe, the post-install directive can also configure Jupiter with your key bindings. The talkcfg program should be in the standard Linux PATH, or you can use an absolute path for this utility.
The dectalk card and its resident software are bundled separately. At bootup, your computer must download the Dectalk software into the card, or it won't say a thing. Once again I use the /proc file system, rather than creating a lot of new ioctl calls. The directory /proc/accessibility/jupiter will contain three card-specific files, in addition to buf1 through buf6. These are write only files, used to transfer the Dectalk software down to the card. The "firmware" file downloads the kernel, "dict" is for dictionaries, and "exe" is for other executables that run on the card. You might be tempted to simply copy the Dectalk files into their /proc counterparts, but it's safer to use the jdtload utility that I provide. A typical Dectalk load command looks like this.
jdtload kernel.sys dtpc.dic lts.exe ph.exe cmd.exe usa.exe go
Somewhere near the beginning of your startup script, /etc/rc.d/rc.sysinit in Redhat, you should install the Jupiter module, load the Dectalk software as above, and run talkcfg to configure your keyboard, in that order. Remember that you cannot run jdtload until /proc has been mounted. Thus the insmod command can be at the top of the file, to capture as much output as possible, but the next two commands will have to wait until /proc has been mounted.
So -- where do you get all those Dectalk firmware files? Well they came with your card, but they are bundled up in a self-extracting Dos program, to the great annoyance of Linux users everywhere. You have to boot up on Dos, if Dos is on your system, or run dosemu under Linux, or ask a friend with a Dos box for help. Somehow, the install program must be run under Dos, to give you the files you need. And this is all suppose to happen before your synthesizer is talking. :-( In opposition to this Dos-centered mindset, I have some Dectalk files you can use, and they are good enough to get you started, but they won't be the latest and greatest. As soon as you can arrange it, you'll want to use the files that came with your card.
This download procedure also throws a monkey wrench into my rescue floppy disks, since there is no room for the Dectalk firmware on these floppies. Not to worry though - the talking CD rom is coming soon.
Next you will hear the clicks and chirps of your prompt, or any other output messages that may follow the installation of this module. Cat some files and listen to the audio stream. It sounds like an old paper teletype running at 1,500 baud. In fact I created these sounds because I began my programming career on these teletypes, before synthesized speech became affordable, and I could sometimes accomplish a great deal using only this audio feedback. Once you are use to these sounds, type "sync", to safe your file system. (Thanks to NASA, safe has become a verb.) You never know what will happen when you first ask Jupiter to speak, so caution is in order.
Now hit F9. This is initially bound to a command that toggles single-line reading mode. In other words, we are still cautious -- still not messing with the synthesizer. You should hear a short high tone as the mode is enabled. Hit the key again and note the short low tone of a disabled mode. Repeat this, and gain some confidence; Jupiter is intersepting keyboard input and interpreting it properly.
Finally you are ready to invoke speech. Hit F5 to read the last complete line. If you got a buzz at startup, you'll get another buzz now, because we're not connected to the synthesizer. We need to fix this problem, if possible. Forget autoprobe -- it didn't work. Hit alt-r, followed by a digit from 0 to 3, indicating the serial port. For you DOS folks, ttyS0 is com1, and so on. This does not trigger the verification sequence, as autoprobe does, so silence isn't always golden, but it's a good sign. Another buzzer is definitely a bad sign. Make sure your synthesizer is properly connected and turned on, and make sure you've specified the right serial port.
Let's suppose you've gotten past the nasty buzzers. Hit F5 again, and you should hear the last complete line, which is the sync command that you typed in (since sync produces no output). If you hear this output, hit F5 again and again, in quick succession, so that each interrupts the previous. The synthesizer should interrupt each instance of the word "sync" to read the next. In other words, you are testing the shut-up feature, which varies from one model to another. If Jupiter is assuming a generic synthesizer, it assumes ^X is the shut-up character. If this is not the case for your unit, speech will not be interruptable.
Now test flow control by hitting F7 and F2. This moves to the top of the buffer and starts reading. Make sure you left single-line mode off (when you were playing with F9). If you hear a continuous parade of coherent sentences, you're in good shape. If phrases, words, and even parts of words are omitted, Jupiter is sending text faster than the synthesizer can receive it. In other words, flow control isn't working. The default flow control is CTS, an RS-232 standard. If your unit has any other type of flow control, such as x-on x-off, we need to add support for this in tc_synth.c. It's not hard to do; I just haven't done it yet. All the units I've worked with use CTS.
Even if shut-up and flow control don't work, you can get quite a bit done. If you're hearing words, the aforementioned shortcomings are merely inconveniences. If you haven't gotten any words yet, or you only get one word every few seconds, hit alt-o. This activates override mode, so that Jupiter pays no attention to the DSR or CTS signals. Flow control is guaranteed to fail now, as text is sent to the unit on blind faith. But if your unit is connected, and at the appropriate baud rate (9600 by default), you should definitely hear something now.
Once you hear words and start using the system, you will find that the assigned functions are not right for you. There are no key commands to interrogate individual words or letters, and for you screen-mode users, there is no way to locate the visual cursor on the screen. You need to load a configuration file. If you've made your own, via some other talking system, great. But if not, use one that comes with this package; either the Speakup version or my version. This won't be right for you either, but it's a start. Import the talkcfg utility and the config files, and run "talkcfg jup_??.cfg". Note that post-install does this for you, if you ran modprobe Jupiter. If you load my config file, control keys interrogate letters and words, and shifted function keys perform exotic functions. Review the config files; they are well commented.
As a final test, hit F7 shift-F7 sync <return>. This starts at the top of the buffer and looks for the word sync, which you typed in earlier. Jupiter should find this text fragment without difficulty, and proudly say "sync".
The next thing you will want to do is restructure the config file to suit your needs and working conditions. If you spend a lot of time in screen mode, you will probably want to replace most of my key bindings. I don't have any commands to read the character, word, or line indicated by the visual cursor, but you will want these, and more. If you spend 8 hours a day working on a fixed screen, such as order entry, you can build keystrokes that jump straight to the fifth line, third word. Perhaps this is the customer's name, or his account balance. Jupiter is a system that isn't very good at the start, but it can make you incredibly productive if you work at it. As always, I am ready to answer any questions. Contact me via email at karl@eklhad.net, or by phone at (USA) 248-524-1004 during regular business hours EST.