Speech Rate - Text-To Speech In iOS

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. :slight_smile:

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. :slight_smile: