home *** CD-ROM | disk | FTP | other *** search
- /* Talk V1.0 - by Rob Verver in 1992 */
- /* */
- /* With this shellcommand you can make the narrator say any text using the */
- /* new OS2 features. See the helptemplate for more info. When specifying */
- /* a value which is out of range, the correct range will be displayed. */
- /* */
- /* Possible enhancements: */
- /* Ability to speak phonetic strings */
- /* Input from standard input, for piping */
- /* Preferences file in ascii format, controling all settings */
- /* Escape codes changes values halfway a text */
-
- OPT OSVERSION=37
-
- MODULE 'Translator', 'devices/narrator', 'dos/dos', 'exec/memory', 'exec/io'
-
- CONST AUDIOCHANSIZE=4
- ENUM NONE, ERR_DOS, ERR_MEM, ERR_FILE, ERR_DEVICE, ERR_TRANS, ERR_INVALID
-
- OBJECT arglist
- file, rate, pitch, robotic, female, volume, enthusiasm, perturb, f1adj,
- f2adj, f3adj, a1adj, a2adj, a3adj, articulate, centralize, centphon, avbias,
- afbias, priority
- ENDOBJECT
-
- DEF template, args: arglist, phonebuf=NIL, rdargs=NIL, file=NIL, msgport=NIL,
- filebuf=NIL, ioreq: PTR TO ndi, audiochan: PTR TO CHAR, valid=TRUE,
- length, phonebufsize
-
- PROC main () HANDLE
- audiochan := [3, 5, 10, 12]:CHAR
-
- /* parse commandline options */
- args := [NIL, [DEFRATE], [DEFPITCH], 0, 0, [DEFVOL], [DEFF0ENTHUS],
- [DEFF0PERT], [0], [0], [0], [0], [0], [0], [DEFARTIC],
- [DEFCENTRAL], NIL, [0], [0], [25]]: arglist
- template := 'FILE,RATE/K/N,PITCH/K/N,ROBOTIC/S,FEMALE/S,VOLUME/K/N,' +
- 'ENTHUSIASM/K/N,PERTURB/K/N,F1ADJ/K/N,F2ADJ/K/N,F3ADJ/K/N,' +
- 'A1ADJ/K/N,A2ADJ/K/N,A3ADJ/K/N,ARTICULATE/K/N,CENTRALIZE/K/N,' +
- 'CENTPHON/K,AVBIAS/K/N,AFBIAS/K/N,PRIORITY/K/N'
- rdargs := ReadArgs (template, args, NIL)
- IF rdargs=NIL THEN Raise (ERR_DOS)
-
- /* open translator library */
- translatorbase := OpenLibrary ('translator.library', 37)
- IF translatorbase=NIL THEN Raise (ERR_TRANS)
-
- /* open input file */
- file := Open (args.file, MODE_OLDFILE)
- IF file=NIL THEN Raise (ERR_FILE)
- length := FileLength (args.file) /* !!! ascii, no fh */
- IF length<1 THEN Raise (ERR_FILE)
-
- /* allocate input buffer */
- filebuf := AllocVec (length, MEMF_PUBLIC)
- IF filebuf=NIL THEN Raise (ERR_MEM)
-
- /* allocate buffer for phonetic strings */
- phonebufsize := Shl (length, 1)
- phonebuf := AllocVec (phonebufsize, MEMF_PUBLIC)
- IF phonebuf=NIL THEN Raise (ERR_MEM)
-
- /* open narrator device */
- msgport := CreateMsgPort ()
- IF msgport=NIL THEN Raise (ERR_DEVICE)
- ioreq := CreateIORequest (msgport, SIZEOF ndi)
- IF ioreq=NIL THEN Raise (ERR_DEVICE)
- ioreq.flags := NDF_NEWIORB
- IF OpenDevice ('narrator.device', 0, ioreq, NIL)<>NIL THEN Raise (ERR_DEVICE)
-
- /* check values validity */
- checkVal (Long (args.rate), MINRATE, MAXRATE, 'Invalid rate')
- checkVal (Long (args.pitch), MINPITCH, MAXPITCH, 'Invalid pitch')
- checkVal (Long (args.volume), MINVOL, MAXVOL, 'Invalid volume')
- checkVal (Long (args.centralize), MINCENT, MAXCENT, 'Invalid centralization')
- IF valid=FALSE THEN Raise (ERR_INVALID)
-
- ioreq.chmasks := audiochan
- ioreq.nummasks := AUDIOCHANSIZE
-
- /* init values */
- ioreq.rate := Long (args.rate)
- ioreq.pitch := Long (args.pitch)
- ioreq.volume := Long (args.volume)
- ioreq.f0enthusiasm := Long (args.enthusiasm)
- ioreq.f0perturb := Long (args.perturb)
- ioreq.f1adj := Long (args.f1adj)
- ioreq.f2adj := Long (args.f2adj)
- ioreq.f3adj := Long (args.f3adj)
- ioreq.a1adj := Long (args.a1adj)
- ioreq.a2adj := Long (args.a2adj)
- ioreq.a3adj := Long (args.a3adj)
- ioreq.articulate := Long (args.articulate)
- ioreq.centralize := Long (args.centralize)
- ioreq.centphon := Long (args.centphon)
- ioreq.avbias := Long (args.avbias)
- ioreq.afbias := Long (args.afbias)
- ioreq.priority := Long (args.priority)
- IF args.robotic<>NIL THEN ioreq.mode := ROBOTICF0 ELSE ioreq.mode := MANUALF0
- IF args.female<>NIL THEN ioreq.sex := FEMALE
-
- process ()
-
- Raise (0)
- EXCEPT
- SELECT exception
- CASE ERR_DOS; PrintFault (IoErr(), 'Error')
- CASE ERR_MEM; PutStr ('Error: not enough memory\n')
- CASE ERR_FILE; PutStr ('Error: couldn\at open file\n')
- CASE ERR_DEVICE; PutStr ('Error: couldn\at open narrator device\n')
- CASE ERR_TRANS; PutStr ('Error: could\at open translator library V37\n')
- CASE ERR_INVALID; PutStr ('Error: wrong parameters\n')
- ENDSELECT
-
- IF ioreq<>NIL THEN CloseDevice (ioreq) BUT DeleteIORequest (ioreq)
- IF translatorbase<>NIL THEN CloseLibrary (translatorbase)
- IF rdargs<>NIL THEN FreeArgs (rdargs)
- IF phonebuf<>NIL THEN FreeVec (phonebuf)
- IF filebuf<>NIL THEN FreeVec (filebuf)
- IF file<>NIL THEN Close (file)
- IF msgport<>NIL THEN DeleteMsgPort (msgport)
- IF exception THEN CleanUp (10)
- ENDPROC
-
- PROC checkVal (val, min, max, str)
- IF val<min OR (val>max)
- Vprintf ('%s: valid values are between %ld and %ld\n', [str, min, max])
- valid := FALSE
- ENDIF
- ENDPROC
-
- PROC process ()
- DEF readlen /* !!!! was equal to globvar */
-
- readlen := Read (file, filebuf, length)
- IF readlen<>length THEN Raise (ERR_FILE)
-
- Translate (filebuf, length, phonebuf, phonebufsize)
- /* WriteF ('phonetic string:\s\n', phonebuf) */
- speakBuffer (phonebuf, StrLen (phonebuf))
- ENDPROC
-
- PROC speakBuffer (buffer, length)
- DEF ior:PTR TO iostd
- ior := ioreq
- ior.command := CMD_WRITE
- ior.data := buffer
- ior.length := length
- DoIO (ioreq)
- ENDPROC
-