Hi,
I was messing around with the Speak Example for iOS so you can have the contents of a text area read out loud. It works great, but it reads super fast. How can you slow down the rate in which the text is read? I don’t see any code for doing this in the example.
Any help would be greatly appreciated.
The code from the example is:
[code] // #import <AVFoundation/AVFoundation.h>
//
// AVSpeechSynthesizer *av = [[AVSpeechSynthesizer alloc] init];
// AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc]initWithString:@“Text to say”];
// [av speakUtterance:utterance];
// https://developer.apple.com/library/ios/Documentation/AVFoundation/Reference/AVSpeechUtterance_Ref/index.html#//apple_ref/occ/instm/AVSpeechUtterance/initWithString:
// https://developer.apple.com/library/ios/Documentation/AVFoundation/Reference/AVSpeechSynthesizer_Ref/index.html#//apple_ref/occ/instm/AVSpeechSynthesizer/speakUtterance:
// Common Declares
Declare Function alloc Lib “Foundation” selector “alloc” (classRef As Ptr) As Ptr
Declare Function NSClassFromString Lib “Foundation” (classname As CFStringRef) As Ptr
// Create an utterance instance with the specified text
// AVSpeechUtterance *utterance = [[AVSpeechUtterance alloc]initWithString:@“Text to say”];
Static AVSpeechUtterance As Ptr = NSClassFromString(“AVSpeechUtterance”)
Dim utterance As Ptr = alloc(AVSpeechUtterance)
Declare Function initUtterance Lib “AVFoundation” Selector “initWithString:” (id As Ptr, theText As CFStringRef ) As Ptr
Dim initPtr As Ptr = initUtterance(utterance, txtQuestion.Text + “A.” + txtA.Text + “B.” + txtB.Text + “C.” + txtC.Text + “D.” + txtD.Text)
// Create an instance of AVSpeechSynthesizer
// AVSpeechSynthesizer *av = [[AVSpeechSynthesizer alloc] init];
Declare Function init Lib “AVFoundation” Selector “init” (id As Ptr) As Ptr
Static AVSpeechSynthesizer As Ptr = NSClassFromString(“AVSpeechSynthesizer”)
Dim synthesizer As Ptr = init(alloc(AVSpeechSynthesizer))
// Speak the utterance
// [av speakUtterance:utterance];
Declare Sub speakUtterance Lib “AVFoundation” Selector “speakUtterance:” (id As Ptr, utterance As Ptr )
speakUtterance(synthesizer, initPtr)[/code]
Hi Jean-Paul,
Thanks so much for helping me. Where do I put this code? I just stuck it in the beginning of the code above, but it does not seem to do anything. I don’t see where you actually change the rate.
I’m sorry Jean-Paul. I’m totally lost. I can’t follow what is going on above. I try using the code above and I get a bunch of errors.
I put this code directly into the Speak Example, and replaced the existing code but is does not change the rate. It still reads super fast. What am I doing wrong?
[code] Declare Function alloc Lib “Foundation” selector “alloc” (classRef As Ptr) As Ptr
Declare Function NSClassFromString Lib “Foundation” (classname As CFStringRef) As Ptr
Declare sub setRate Lib “AVFoundation” Selector “setRate:” ( obj As ptr, rate as single) // obj = utterance
Static AVSpeechUtterance As Ptr = NSClassFromString(“AVSpeechUtterance”)
Dim utterance As Ptr = alloc(AVSpeechUtterance)
setRate(utterance,0.7)
Declare Function initUtterance Lib “AVFoundation” Selector “initWithString:” (id As Ptr, theText As CFStringRef ) As Ptr
Dim initPtr As Ptr = initUtterance(utterance, SpeakArea.Text)
// Create an instance of AVSpeechSynthesizer
// AVSpeechSynthesizer *av = [[AVSpeechSynthesizer alloc] init];
Declare Function init Lib “AVFoundation” Selector “init” (id As Ptr) As Ptr
Static AVSpeechSynthesizer As Ptr = NSClassFromString(“AVSpeechSynthesizer”)
Dim synthesizer As Ptr = init(alloc(AVSpeechSynthesizer))
// Speak the utterance
// [av speakUtterance:utterance];
Declare Sub speakUtterance Lib “AVFoundation” Selector “speakUtterance:” (id As Ptr, utterance As Ptr )
speakUtterance(synthesizer, initPtr)[/code]
I still must be doing something wrong. I changed the speed to setRate(utterance, 0.05) and tested it on the device. Its still speaks fast. Below is the project link that I’m using.
link text
Thanks Jean-Paul. I appreciate it.
You’ve got setRate: as a single, but are passing it a float.
Hi Tim. If I change it to a Float from a Single it won’t work at all.
Changing it from a single to a double does not work. Still reads really fast.
[code]Declare Function alloc Lib “Foundation” selector “alloc” (classRef As Ptr) As Ptr
Declare Function NSClassFromString Lib “Foundation” (classname As CFStringRef) As Ptr
Declare sub setRate Lib “AVFoundation” Selector “setRate:” ( obj As ptr, rate as double) // obj = utterance
Static AVSpeechUtterance As Ptr = NSClassFromString(“AVSpeechUtterance”)
Dim utterance As Ptr = alloc(AVSpeechUtterance)
setRate(utterance,0.7)
Declare Function initUtterance Lib “AVFoundation” Selector “initWithString:” (id As Ptr, theText As CFStringRef ) As Ptr
Dim initPtr As Ptr = initUtterance(utterance, txtQuestion.Text + “A.” + txtA.Text + “B.” + txtB.Text + “C.” + txtC.Text + “D.” + txtD.Text)
// Create an instance of AVSpeechSynthesizer
// AVSpeechSynthesizer *av = [[AVSpeechSynthesizer alloc] init];
Declare Function init Lib “AVFoundation” Selector “init” (id As Ptr) As Ptr
Static AVSpeechSynthesizer As Ptr = NSClassFromString(“AVSpeechSynthesizer”)
Dim synthesizer As Ptr = init(alloc(AVSpeechSynthesizer))
// Speak the utterance
// [av speakUtterance:utterance];
Declare Sub speakUtterance Lib “AVFoundation” Selector “speakUtterance:” (id As Ptr, utterance As Ptr )
speakUtterance(synthesizer, initPtr)[/code]
Hi Jean-Paul. You’re a genius!!! That worked great!! Thanks so much!! It works perfectly on the iPad. Xojo should add this to their example.
I just have one last question. Do you know if there a command to stop or interrupt the speech? So, when it starts reading you can stop it?
I think I have bugged you enough today. You were a great help. I really appreciate you taking the time to help me. Thanks again.
James
I’m sorry Jean Paul, I don’t know how to do that. Since there is no documentation anywhere for the Text-To-Speech on Xojo iOS, I don’t know where to look.
Okay I put this code on a “STOP” button, but it does not work. The speech keeps going. Will this code just lower the volume to 0? Does it actually stop the speech? I would like it so the user can just stop the speech, click another button and the speech starts again. I’m really sorry to keep bugging you about this.
[code] // Common Declares
Declare Function alloc Lib “Foundation” selector “alloc” (classRef As Ptr) As Ptr
Declare Function NSClassFromString Lib “Foundation” (classname As CFStringRef) As Ptr
Static AVSpeechUtterance As Ptr = NSClassFromString(“AVSpeechUtterance”)
Dim utterance As Ptr = alloc(AVSpeechUtterance)
#if Target32Bit then
Declare sub setVolume Lib "AVFoundation" Selector "setVolume:" ( obj As ptr, z as single)
#Endif
#if Target64Bit then
Declare sub setVolume Lib "AVFoundation" Selector "setVolume:" ( obj As ptr, z as double)
#Endif
setVolume(utterance,0.)[/code]
This stuff’s not easy. I appreciate your help.