changing sapi voices

General FreeBASIC programming questions.
TESLACOIL
Posts: 1769
Joined: Jun 20, 2010 16:04
Location: UK
Contact:

changing sapi voices

Postby TESLACOIL » Jan 19, 2011 3:39

changing sapi voices sapi4 & sapi5

Is there some FB code that will let you choose what sapi voice you want to do the talking ?

I have a number of FB progs that convert text to speech text but dont know how to select or change the voice from within FB

what needs adding to this in order to change the default voice (which is M$ mary as far as i can tell) though M$ sam is the stuck choice in control panel/speech. it is M$ mary that plays with this code below

sapi4 code plays a female voice for me m$ mary

Code: Select all

'speech => SAPI4 test, Windows only
#define UNICODE
#include once "disphelper/disphelper.bi"
#include once "windows.bi"
'
dim myt as wstring * 512
dim as integer isSpeaking
dim as HRESULT hr
DISPATCH_OBJ(tts)
'
screen 13
WindowTitle "SAPI 4 Test"
print "Attempting speech now"
print
'
dhInitialize( TRUE )
dhToggleExceptions(FALSE) 'set this true to get error codes
'
myt="Speech.VoiceText" 'SAPI 4
hr=dhCreateObject(@myt, NULL, @tts)
if hr<>0 then
   print "Problems encountered, speech failed,"
   print "  sleeping to exit"
   sleep
   end
end if
'
dhCallMethod(tts, ".Register(%S, %S)", "", @"DispHelper Sample Application")
dhPutValue(tts, ".Enabled = %b", TRUE)
'

myt="SAPIhlh Version 4 was found on your computer."
dhCallMethod(tts, ".Speak(%S, %d)", @myt, 1)
'myt="SA your computer."
'dhCallMethod(tts, ".Speak(%S, %d)", @myt, 1)

'
isSpeaking=1
while isSpeaking=1
   sleep 100
   dhGetValue("%b", @isSpeaking, tts, ".IsSpeaking")
wend
'
print "SAPI Version 4 found"
print "Done, sleeping"
sleep
SAFE_RELEASE(tts)
end
 
 
 'not FreeBASIC below !!!
 'Module TTSHelloWorld
  '  Sub Main()
   '     Dim ttsVoice As New Speech.Synthesis_SpeechSynthesizer         ttsVoice.speak(“Hello world!”)
    'End Sub
'End Module




I have dozens of installed voices and can choose them at will if i run various this app or that app

M$sam seems to be stuck with windows narrator

----------------------------------------------------

[i]off topic from sapi voice question i found this link for speech macros[/i]may come in handy at some stage

http://code.msdn.microsoft.com/wsrmacros/Wiki/View.aspx?title=speechMacros&referringTitle=Command%20Set
Last edited by TESLACOIL on Jan 19, 2011 3:54, edited 3 times in total.
TESLACOIL
Posts: 1769
Joined: Jun 20, 2010 16:04
Location: UK
Contact:

sapi5 code

Postby TESLACOIL » Jan 19, 2011 3:50

sapi5 code
plays a male voice for me M$ sam

Code: Select all




'speech => SAPI5 test, Windows only
#define UNICODE
#include once "disphelper/disphelper.bi"
#include once "windows.bi"
'
dim myt as wstring * 512
dim as integer isSpeaking
dim as HRESULT hr
DISPATCH_OBJ(tts)
'
screen 13
WindowTitle "SAPI 5 Test"
print "Attempting speech now"
print
'
dhInitialize( TRUE )
dhToggleExceptions(FALSE) 'set this TRUE to get error codes
'
myt="Sapi.SpVoice"     'SAPI 5
hr=dhCreateObject(@myt, NULL, @tts)
if hr<>0 then
   print "Problems encountered, speech failed,"
   print "  sleeping to exit"
   sleep
   end
end if
'
myt="SAPI Version 5 was found on your computer."
dhCallMethod(tts, ".Speak(%S)", @myt)
'
print "SAPI Version 5 found"
print "Done, sleeping
sleep
SAFE_RELEASE(tts)
end

Loe
Posts: 323
Joined: Apr 30, 2006 14:49

Postby Loe » Jan 19, 2011 14:21

Hi Teslacoil,

here
http://freebasic.net/forum/viewtopic.php?t=16848&highlight=recognizer
FB code of SAPI5 for speech recognizer, change voice and text to speech

for the short code only for voice change and text to speech

Code: Select all

#include once "windows.bi"
#Include Once "axobj2.bi"

Dim As lpdispatch spvoice,tokens
Dim As integer i
Dim As variant locale,item,vtoken,vtext,reqattr=""
Dim As String text

'initialize axsupport
axinit
'creating spvoice object
axcreateobject("SAPI.SpVoice",spvoice)
If axscode<>s_ok Then ?"Can't initialize SAPI, error:" & axscode:Sleep:end(0)

'get tokens collection
tokens=*objget(spvoice,"getvoices@1",@reqattr).var_.pdispval

'enumerate available token
For i =0 To *objget(tokens,"Count")-1
   item=i
   ?i & ". " & *objget(tokens,"Item@1.GetDescription@1",@item,@locale)
Next

Input "Select voice no:",i
item=i
'get selected token address
vtoken=*objget(tokens,"Item@1",@item)
'set voice token
objset spvoice,"Voice@1",@vtoken
'define spech content->change to wstring
text="Voice changed to " & *objget(tokens,"Item@1.GetDescription@1",@item,@locale)
vtext=WStr(text)
'speak with selected token
objcall spvoice,"Speak@1",@vtext
?"press any key"
Sleep

*it use axobj2.bi and FB variant lib as linked above
TESLACOIL
Posts: 1769
Joined: Jun 20, 2010 16:04
Location: UK
Contact:

free voices

Postby TESLACOIL » Jan 19, 2011 22:14

do you know if will it work with Lernout & Hauspie Text To Speech engines ?


http://nextup.com/TextAloud/SpeechEngin ... freevoices

I was looking though the registry , & the voices have different parameters , prolly half a dozen different kinds of voice type settings.

---------------------------------------------------------------------

I had followed your link. There seems to be quite a lot involved gluing together all the files to make it work. Is there a stepwise guide on how to assemble it all ?
Loe
Posts: 323
Joined: Apr 30, 2006 14:49

Postby Loe » Jan 19, 2011 23:08

textaloud is an application that use sapi4 or 5, if installed voice can seen via sapi control panel, so the code will work.
about the link, you only need compiled libvariant.a. i'll send you, if you want it
Loe
Posts: 323
Joined: Apr 30, 2006 14:49

Postby Loe » Jan 20, 2011 3:01

I'll try to change short code to disphelper.
Here we go

Code: Select all

#define UNICODE
#include once "windows.bi"
#include once "disphelper/disphelper.bi"

Dim As zString ptr text
Dim As Integer count,i

'define required object
DISPATCH_OBJ(spvoice)
DISPATCH_OBJ(tokens)
DISPATCH_OBJ(token)

dhInitialize( TRUE )
dhToggleExceptions(true) 'set this TRUE to get error codes

If dhCreateObject("sapi.spvoice", NULL, @spvoice)<>0 Then
   print "Problems encountered, speech failed,"
   print "  sleeping to exit"
   sleep
   end
EndIf

dhCallMethod(spvoice, ".Speak(%s)", "SAPI Version 5 was found on your computer.")

'get and enumerate available token
dhGetValue( "%o", @tokens, spvoice, ".getvoices(%s)","") 'get token collection
dhGetValue( "%d", @count, tokens, ".count") 'number of available token

'list descrition of all available token
For i=0 To count-1
   dhGetValue( "%s", @text, tokens, ".item(%d).getdescription(%d)",i,0) 'get description of each token, please correct it
   ?i & ". " & text
Next

'change voice
input"Select voice no?",i
dhGetValue( "%o", @token, tokens, ".item(%d)",i) 'get the token of the voice first
dhputref(spvoice,".voice=%o",token) 'it is putref method, my misataken

'speak With selected voice
dhCallMethod(spvoice, ".Speak(%s)", "SAPI Version 5 was found on your computer.")

?"press any key"
Sleep

*revised 1: thx to phisguy
*revised 2: change dhputvalue to dhputref, it work now
Last edited by Loe on Jan 20, 2011 8:34, edited 3 times in total.
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Postby phishguy » Jan 20, 2011 3:56

This works for getting the description. I haven't figured out changing the voice yet.

Code: Select all

Dim As zstring ptr text

For i=0 To count-1
        dhGetValue( "%s", @text, tokens, ".item(%d).getdescription(%d)",i,0) 'get description of each token, please correct it
        ?i & ". " & *text
Next
Loe
Posts: 323
Joined: Apr 30, 2006 14:49

Postby Loe » Jan 20, 2011 4:07

it is weird, voice method not recognized by disphelper.
Voice method exist in ISpeechVoice interface.
In VB the command could be spvoice.voice=token,
anyway it work in axsupport dispatch automation mode.
Loe
Posts: 323
Joined: Apr 30, 2006 14:49

Postby Loe » Jan 20, 2011 8:30

Gotcha!!!!
Didnt notice thereis putref method in disphelper.
Change dhput value to dhputref, it work now
phishguy
Posts: 1201
Joined: May 05, 2006 16:12
Location: West Richland, Wa

Postby phishguy » Jan 20, 2011 22:28

Loe.

That's the first time I've seen dhputref used. What does this do differently? Do you have any documentation on this function and its usage?
TESLACOIL
Posts: 1769
Joined: Jun 20, 2010 16:04
Location: UK
Contact:

prog i use

Postby TESLACOIL » Jan 21, 2011 0:31

prog i use to preview and save to wav is texttowav

ver 1.5 beta unicode 388 KB
it uses the lame_enc.dll 492 KB

it allows me to choose sapi4 and sapi5 voices from lots of different voice makers

they appear to have different tolken values in the registry , so it may not be a simple task to have a universal voice player/saver

it would be an awesome utility if there was a prog like texttowav written in freebasic


This would enable auto generation of a wav database of word phrases & phonetics in any voice / voice setting you chose (pitch speed volume)

as well as on the fly voice playback

you could feed it dictionaries or whole books , go for a walk round the block and all the hard work is done for you




there seems to be some extra code in texttowav (or embedded with the voices) because words said in a sentence have a different sound and rhythm to those said in isolation. Also some voices say KB as KayBee or as kilobyte

i realy like Carol , one of the L&H sapi 4 voices

robosoft 4 and Mary in space are good too, both are sapi4 voices
Last edited by TESLACOIL on Jan 21, 2011 1:00, edited 1 time in total.
TESLACOIL
Posts: 1769
Joined: Jun 20, 2010 16:04
Location: UK
Contact:

web page with registry info

Postby TESLACOIL » Jan 21, 2011 0:56

web page with registry info for sapi voices

http://www.webbie.org.uk/changingNarrat ... 5Voice.htm

this may be useful

extract


# Open the registry key for the voice you want Narrator to use. For RealSpeak voices I've found that you need six values:

* CLSID (should be a long string of characters, like "{CAC6785B-655E-4ae1-A656-BDEFD18DC46C}")
* LangCode (should be a three-character code, e.g. "ENG" for British English)
* Language (a descriptive name for the voice language, e.g. "British English")
* VoiceName (e.g. "Daniel")
* Frequency (e.g. "22")
* VoiceData (the path to the data file for the voice, e.g. "C:\Program Files\ScanSoft\RealSpeak Solo V4\speech\components\data\Daniel.dat")

For eSpeak voices you need two values:

* CLSID (should be a long string of characters, like "{BE985C8D-BE32-4A22-AA93-55C16A6D1D91}")
* VoiceName (e.g. "en-sc")

Ian Sharpe reports it's even easier for AT&T voices:

* CLSID (should be a long string of characters, like "{CAC6785B-655E-4ae1-A656-BDEFD18DC46C}".)

Charl Barnard reports that for Cepstral voices I strongly suspect that different SAPI5 voices will require different keys. If you find out any, do let me know.
# Open the MSSam registry key. You'll see that some of the values are there (e.g. CLSID) and some are not (e.g. VoiceName).
# Apply the values from your chosen voice to the MSSam registry key. This will mean editing existing values and adding some new ones. Do not change the (Default) or 409 values, or any of the subkeys.
# Here is a working hacked MSSam registry entry changed to use RealSpeak Solo Daniel:
Loe
Posts: 323
Joined: Apr 30, 2006 14:49

Postby Loe » Jan 21, 2011 1:31

@phisguy
here invoke kind list of COM/ActiveX

Code: Select all

'CONST DISPATCH_METHOD         = 1  ' The member is called using a normal function invocation syntax.
'CONST DISPATCH_PROPERTYGET    = 2  ' The function is invoked using a normal property-access syntax.
'CONST DISPATCH_PROPERTYPUT    = 4  ' The function is invoked using a property value assignment syntax.
'CONST DISPATCH_PROPERTYPUTREF = 8  ' The function is invoked using a property reference assignment syntax.

we use combination too, if the function has parameter(s), invoke kind is 1+2=3
we use propertyputref when we assign an object, and propertryput to assign value.
Sometimes we can use propertyput both for assign a value or an object, sometime we can not.
In some language propertyputref called SET command, and propertyput as LET.
In axsupport im using objcall, objget, objput, objset respectively.
In disphelper dhcallmethod, dhgetvalue, dhputvalue, dhputref.

@teslacoil
SAPI interface has many function to explore. There is SAPI.CHM to download in m$ website. From the documentation we'll know 'replacement' code with disphelper or my axsupport.
Or in the hard way, we can use Type Library Browser and guess function of the method from its name.
Example:
in ISpeechVoice interface there are following method
-Speak : we knew what it purpose :)
-Voice property: we knew from now on how to handle this with disphelper :)
-Volume property?
-Rate property: hmmm is it for the speed/rate of speak?

If you interrested and good luck ^_^
SevenLegion
Posts: 14
Joined: Dec 30, 2011 13:26

Re: changing sapi voices

Postby SevenLegion » Feb 04, 2012 16:35

Hello Loe,
your example works fine to me and it was succesfull to change voices.
There is only a little problem to solve and unfortunately I'm not an expert of object programming:

you use a loop to show the list of installed voices:

Code: Select all

print "list of all available token:"
For i=0 To count-1
   dhGetValue( "%s", @text, tokens, ".item(%d).getdescription(%d)",i,0) 'get description of each token, please correct it
   ?"voice n.";i; "- " & text
Next


it works but this cant show the voice's names, it show just a list of strange numbers.
ex:

voice n.0 - 144425
voice n.1 - 143782

Well, I've found a promising function on SAPI documentation, the GetAttribute Method:

http://msdn.microsoft.com/en-us/library/ee125591%28v=vs.85%29.aspx

So, I've tried to add a line in your loop:

Code: Select all

print "list of all available token:"
For i=0 To count-1
   dhGetValue( "%s", @text, tokens, ".item(%d).getdescription(%d)",i,0) 'get description of each token, please correct it
   dhGetValue( "%s", @text, tokens, ".item(%d).getattribute(%s)",i,"Language") 'get the Language name
   ?"voice n.";i; "- " & text
Next


I was hoping this would show the voice name, but unfortunately it keeps on showing the previous number...
Anyway the interesting fact is it works without errors until you use standard attribute names, like "Vendor", "Language", "Gender"... even if I dont know how to use it properly

What about?
Loe
Posts: 323
Joined: Apr 30, 2006 14:49

Re: changing sapi voices

Postby Loe » Feb 13, 2012 12:23

hi sevenlegion,
since text declared as zstring pointer, try this

Code: Select all

    print "list of all available token:"
    For i=0 To count-1
       dhGetValue( "%s", @text, tokens, ".item(%d).getdescription(%d)",i,0) 'get description of each token, please correct it
       ?"voice n.";i; "- " & *text
       dhGetValue( "%s", @text, tokens, ".item(%d).getattribute(%s)",i,"Language") 'get the Language name
       ?"voice n.";i; "- " & *text
    Next


if it not work, try chage text to fixedstring such as zstring*255,
?"voice n.";i; "- " & text

Return to “General”

Who is online

Users browsing this forum: No registered users and 7 guests