OSXOperatingSystem.st
changeset 22966 57d20ca389c1
parent 22962 4352599df059
child 22970 ff49ded84d3a
--- a/OSXOperatingSystem.st	Sun May 20 09:50:05 2018 +0200
+++ b/OSXOperatingSystem.st	Sun May 20 09:50:13 2018 +0200
@@ -885,13 +885,72 @@
     "
 !
 
-speak:aString
-    "use 'say ...'"
+speak:aString voiceName:voiceName
+    "uses 'say ...'
+     The given voiceName is translated via the voiceMapping to one of
+     my installed standard voices, or passed as-is, if no mapping is found."
+
+    |mapping voiceUsed cmd|
+
+    mapping := self voiceMapping detect:[:v | v key = voiceName] ifNone:[(voiceName -> voiceName)].
+    voiceUsed := mapping value.
+    (voiceUsed isNil or:[voiceUsed = 'default']) ifTrue:[
+        cmd := 'say "%2"'        
+    ] ifFalse:[
+        cmd := 'say -v "%1" "%2"'        
+    ].    
+    ^ self executeCommand:(cmd bindWith:voiceUsed with:aString withCEscapes)
+
+    "portable:
+     self speak:'hello world - this is the default voice' voiceName:nil
+     self speak:'hello world - this is a computer voice' voiceName:'computer'
+     self speak:'hello world - this is a male voice' voiceName:'male'
+     self speak:'hello world - this is a female voice' voiceName:'female'
+
+    non-portable (OSX only):     
+     self speak:'hello world - this is a scottish female voice' voiceName:'Fiona'
+     self speak:'hello world - this is a german female voice' voiceName:'Anna'
+     self speak:'hello world - this is a chinese female voice' voiceName:'Ting-Ting'
+     self speak:'hello world - this is an indian female voice' voiceName:'Veena'
+     self speak:'hello world - this is a french female voice' voiceName:'Amelie'
+     self speak:'hello world - this is an italian female voice' voiceName:'Alice'
+     self speak:'hello world - this is a russian female voice' voiceName:'Milena'
 
-    ^ self executeCommand:('say "%1"' bindWith:aString)
+     self speak:'hello world - this is a pipe organ speaking' voiceName:'Pipe Organ'
+     self speak:'hello world - happy birthday to you' voiceName:'Good News'
+    "
+!
+
+voiceInfo
+    "return a list of available voices plus info:
+     for each available voice, a triple is returned, containing:
+        voiceName language_territory comment/description
+    "
+
+    ^ (PipeStream outputFromCommand:'say -v ?')
+        asCollectionOfLines
+            collect:[:l |
+                |s name lang comment|
+                
+                s := l readStream.
+                "/ skip forward for two separators
+                [
+                    [s next isLetterOrDigit] whileTrue:[].
+                    s peek isLetterOrDigit
+                ] whileTrue.
+                name := l copyFrom:1 to:s position - 1.
+                s skipSeparators.
+                lang := s upToSeparator.
+                s skipSeparators.
+                s next == $# ifTrue:[
+                    s skipSeparators.
+                    comment := s upToEnd utf8Decoded.
+                ].
+                { name . lang . comment }
+            ]    
 
     "
-     self speak:'hello world'
+     OperatingSystem voiceInfo
     "
 ! !