#FEATURE by cg
authorClaus Gittinger <cg@exept.de>
Sun, 20 May 2018 09:50:05 +0200
changeset 22965 0d1b7bb49334
parent 22964 22af4adfa337
child 22966 57d20ca389c1
#FEATURE by cg class: AbstractOperatingSystem class definition class: AbstractOperatingSystem class added: #voiceMapping #voiceMapping: comment/format in: #playSound: #speak: #speak:voiceName: changed: #voiceInfo
AbstractOperatingSystem.st
--- a/AbstractOperatingSystem.st	Sun May 20 09:21:11 2018 +0200
+++ b/AbstractOperatingSystem.st	Sun May 20 09:50:05 2018 +0200
@@ -18,7 +18,7 @@
 Object subclass:#AbstractOperatingSystem
 	instanceVariableNames:''
 	classVariableNames:'ConcreteClass ErrorSignal LastErrorNumber LocaleInfo OSSignals
-		PipeFailed Resources'
+		PipeFailed Resources VoiceMapping'
 	poolDictionaries:''
 	category:'System-Support'
 !
@@ -6585,7 +6585,8 @@
 !AbstractOperatingSystem class methodsFor:'sound & voice'!
 
 playSound:fileName
-    "unsupported - simply stay silent"
+    "play a soundfile (wav)
+     unsupported - simply stay silent"
 
     ^ self.
 !
@@ -6599,31 +6600,48 @@
 speak:aString
     "say something in the default voice"
     
-    self speak:aString voiceName:nil.
+    self speak:aString voiceName:'default'.
+
+    "
+     OperatingSystem speak:'hello world'
+    "
 !
 
 speak:aString voiceName:aVoiceName
-    "voiceName should be in the list of supported voices as returned by
-     voiceInfo. 
-     Use nil for the default (or only available) voice. 
-     Usually, this is the user's preference voice setting."
-     
-    "unsupported - simply stay silent"
+    "voiceName should be in the list of supported voices as returned by voiceInfo,
+     or (better and portable) one of the keys in voiceMapping. 
+     Use nil for the default voice (which is usually the user's preference voice setting in
+     the operating system - eg. system preferences in OSX).
+     For non-existing/unknown voiceNames, the default voice will be used.
+
+     Here, speak is unsupported and the system remains silent.
+     To be redefined in concrete subclasses."
 
     ^ self.
+
+    "
+     OperatingSystem speak:'hello world'
+     OperatingSystem speak:'hello world' voiceName:'female'
+     OperatingSystem speak:'hello world' voiceName:'male'
+     OperatingSystem speak:'hello world' voiceName:'computer'
+    "
 !
 
 voiceInfo
-    "return a list of available voices plus info.
+    "return a list of available (OS-specific) voice names plus info.
      For each available voice, a triple is returned, containing:
         voiceName language_territory comment/description
 
-     the fallback here returns an empty list, meaning that no voice
-     can be chosen. However, it may still be the case that a default voice
-     is present.
+     the language_territory (of the form en_EN / en_US etc.) gives a hint,
+     for which language the voice is best used.
      
-     on OSX, this would look like:
+     The fallback here returns the default list, which should be supported
+     by any system.
+     
+     On OSX, this would look like:
      #(
+        ('default'     'en_US' 'the default system voice')
+
         #('Agnes' 'en_US' 'Isn''t it nice to have a computer that will talk to you?')
         #('Albert' 'en_US' 'I have a frog in my throat. No, I mean a real frog!!')
         #('Alex' 'en_US' 'Most people recognize me by my voice.')
@@ -6634,7 +6652,58 @@
      )     
     "
 
-    ^ #()
+    ^ #(
+        ('default'     'en_US' 'the default system voice')
+    )
+!
+
+voiceMapping
+    "return a mapping from common (OS-independent) voice names
+     to OS-specific names or IDs.
+     The speak:voiceName interface will recgnize both.
+     For portable programs, always use the OS-independent name and
+     let every OS xlate to its internal name."
+
+    "The mapping here maps all common names to the default"
+
+    VoiceMapping notNil ifTrue:[^ VoiceMapping].
+    ^ { 
+        ( 'male' -> nil ) .
+        ( 'female' -> nil ) .
+        ( 'computer' -> nil ) .
+        ( 'default' -> nil )
+    }
+
+    "on OSX, this could be:
+        ^ {
+            'male' -> 'Alex' .
+            'female' -> 'Fiona' .
+            'computer' -> 'Zarvox' .
+            'default' -> 'Fiona'
+        }
+    "
+!
+
+voiceMapping:aMapping
+    "return a mapping from common (OS-independent) voice names
+     to OS-specific names or IDs.
+     The speak:voiceName interface will recgnize both.
+     For portable programs, always use the OS-independent name and
+     let every OS xlate to its internal name."
+
+    "The mapping here maps all common names to the default"
+
+    VoiceMapping := aMapping
+
+    "on OSX, this could be:
+        OperatingSystem voiceMapping:
+            {
+                'male' -> 'Alex' .
+                'female' -> 'Fiona' .
+                'computer' -> 'Zarvox' .
+                'default' -> 'Fiona'
+            }.
+    "
 ! !
 
 !AbstractOperatingSystem class methodsFor:'time and date'!