-
Notifications
You must be signed in to change notification settings - Fork 1
/
Galatea.p
239 lines (210 loc) · 6.71 KB
/
Galatea.p
1
Unit Galatea;(*** v 1.0 12 luglio 1993 MisterAkko 1.0.1 del 23 Agosto 1993 Spostato parte del codice di startup da startup a SpeechAvailable, per evitare che accadano danni se viene chiamato Shutdown senza che Startup sia mai stato chiamato.1.1 del 13 set 93 Aggiunto il software che controlla la disponibilitˆ dei fonemi di una lingua 1.2, 30/6/95 Aggiunta la chiamata GalateaShutup, a beneficio di Dream II ***) InterfaceUses Types, QuickDraw;FUNCTION SpeechAvailable: BOOLEAN;{ Prima funzione da chiamare. Restituisce TRUE se lo Speech Manager disponibile }PROCEDURE GalateaStartup;{ Seconda funzione da chiamare. Inizializza il modulo. }PROCEDURE SelectGender (gender: INTEGER);{ Terza funzione da chiamare. Serve a specificare di che sesso deveessere la voce. Se si include "Speech.p" usare le costanti kNeuter, kMale o kFemale.Altrimenti usare rispettivamente 0, 1, 2. }PROCEDURE SelectLanguageAndGender (language, gender: INTEGER);{ Analoga a SelectGender, pretende anche che siano disponibili i fonemi tipicidella lingua indicata }PROCEDURE GalateaSpeak (textID: INTEGER);{ Dato il resource ID di una risorsa di tipo TEXT, questa funzione fa pronunciareallo speech manager, in modo asincrono, il testo ivi contenuto. }PROCEDURE GalateaShutup;{ Silenzio istantaneo }PROCEDURE GalateaShutdown;{ Per chiudere baracca. }ImplementationUSES GestaltEqu, Memory, Resources, Speech;CONST kSoloTesto = 'TEXT';VAR chan: SpeechChannel; { Il canale che usiamo per parlare } textSpoken: Handle; { Il testo che stiamo pronunciando } currentLanguage, { La lingua umana della voce che stiamo usando } currentGender: INTEGER; { Il sesso della voce che stiamo usando }FUNCTION SpeechAvailable: BOOLEAN;VAR err: OSErr; result: Longint;BEGIN err := Gestalt (gestaltSpeechAttr, result); SpeechAvailable := (err = noErr) & (result <> 0); { Questo starebbe meglio in Startup, ma per evitare il rischio che succedano cose atroci se qualcuno chiama Shutdown senza aver chiamato Startup (perchŽ questa funzione aveva restituito FALSE a tempo debito), li metto qui. } chan := NIL; textSpoken := NIL;END;PROCEDURE GalateaShutup;VAR err: OSErr;BEGIN IF chan <> NIL THEN err := StopSpeech(chan);END;FUNCTION DammiSesso (diCheVoce: VoiceSpec; VAR sesso: INTEGER): OSErr;{ Restituisce il sesso di una voce }VAR err: OSErr; descVoce: VoiceDescription;BEGIN IF diCheVoce.creator = 'mtk2' THEN { Evitiamo la pessima voce di Macintalk II } err := 1 ELSE err := GetVoiceDescription (diCheVoce, descVoce, sizeof (VoiceDescription)); IF (err = noErr) & (descVoce.length > 337) THEN { 337 l'offset del campo gender in VoiceDescription } sesso := descVoce.gender; DammiSesso := errEND;FUNCTION DammiLingua (diCheVoce: VoiceSpec; VAR lingua: INTEGER): OSErr;{ Restituisce la lingua parlata da una voce }VAR err: OSErr; descVoce: VoiceDescription;BEGIN IF diCheVoce.creator = 'mtk2' THEN { Evitiamo la pessima voce di Macintalk II } err := 1 ELSE err := GetVoiceDescription (diCheVoce, descVoce, sizeof (VoiceDescription)); IF (err = noErr) & (descVoce.length > 343) THEN { 343 l'offset del campo language in VoiceDescription } lingua := descVoce.language; DammiLingua := errEND;PROCEDURE SelectGender (gender: INTEGER);VAR textMode: OSType; err: OSErr; voce: VoiceSpec; numVoci, loop: INTEGER; sessoTrovato: INTEGER; trovata: BOOLEAN;BEGIN { Evitiamo un processo costoso in termini di tempo (la selezione di una voce) se il sesso richiesto quello giˆ correntemente selezionato } IF gender = currentGender THEN Exit (SelectGender); { Ok, via col vento } trovata := FALSE; err := CountVoices (numVoci); IF err = noErr THEN BEGIN loop := 1; WHILE (loop <= numVoci) & (trovata = FALSE) & (GetIndVoice (loop, voce) = noErr) DO BEGIN err := DammiSesso (voce, sessoTrovato); IF (err = noErr) & (sessoTrovato = gender) THEN BEGIN trovata := TRUE; { Se c'era un altro canale aperto, chiudilo } IF chan <> NIL THEN err := DisposeSpeechChannel (chan); { Apri il nuovo canale } err := NewSpeechChannel (voce, chan); { Spiega che useremo testo, non fonemi } IF chan <> NIL THEN BEGIN textMode := kSoloTesto; err := SetSpeechInfo (chan, soInputMode, @textMode); END; { Se il canale stato allocato } END; { trovata } loop := succ (loop) END; { while } END { if countVoices could work }END;PROCEDURE SelectLanguageAndGender (language, gender: INTEGER);VAR textMode: OSType; err: OSErr; voce: VoiceSpec; numVoci, loop: INTEGER; linguaTrovata, sessoTrovato: INTEGER; trovata: BOOLEAN;BEGIN { Evitiamo un processo costoso in termini di tempo (la selezione di una voce) se la lingua richiesta quella giˆ correntemente selezionata } IF language = currentLanguage THEN Exit (SelectLanguageAndGender); { Ok, via col vento } trovata := FALSE; err := CountVoices (numVoci); IF err = noErr THEN BEGIN loop := 1; WHILE (loop <= numVoci) & (trovata = FALSE) & (GetIndVoice (loop, voce) = noErr) DO BEGIN err := DammiLingua (voce, linguaTrovata); err := DammiSesso (voce, sessoTrovato); IF (err = noErr) & (linguaTrovata = language) & (sessoTrovato = gender) THEN BEGIN trovata := TRUE; { Se c'era un altro canale aperto, chiudilo } IF chan <> NIL THEN err := DisposeSpeechChannel (chan); { Apri il nuovo canale } err := NewSpeechChannel (voce, chan); { Spiega che useremo testo, non fonemi } IF chan <> NIL THEN BEGIN textMode := kSoloTesto; err := SetSpeechInfo (chan, soInputMode, @textMode); END; { Se il canale stato allocato } END; { trovata } loop := succ (loop) END; { while } IF NOT trovata & (chan <> NIL) THEN BEGIN { Non ho trovato nulla del genere. Disattiva il parlato } err := DisposeSpeechChannel (chan); chan := NIL END; END { if countVoices could work }END;PROCEDURE GalateaSpeak (textID: INTEGER);VAR err: OSErr;BEGIN WHILE SpeechBusy <> 0 DO ; { Aspetta il completamento di eventuale richiesta precedente } IF textSpoken <> NIL THEN { Se c'era giˆ una frase in pronunciaÉ } ReleaseResource (textSpoken); { Éallora liberatene } { OK, carica la nuova risorsa } textSpoken := GetResource (kSoloTesto,textID); IF (textSpoken = NIL) | (ResError <> noErr) THEN Exit (GalateaSpeak); IF chan <> NIL THEN BEGIN HLock (textSpoken); err := SpeakText (chan, textSpoken^, GetHandleSize (textSpoken)); END; { Se c' il canale }END;PROCEDURE GalateaStartup;BEGIN currentLanguage := maxint; currentGender := maxint { Per forzare il caricamento di una voce }END;PROCEDURE GalateaShutdown;VAR err: OSErr;BEGIN IF chan <> NIL THEN err := DisposeSpeechChannel (chan); IF textSpoken <> NIL THEN ReleaseResource (textSpoken)END;END. { Unit }