Tuesday, December 9, 2014

Crazy One.

TTS - text to speech from your phone with Swift is a bit crazy, but fun. 

 

How to create a simple text to speech app for iOS8:


Please note, that TTS did not work for me in the simulator. The build went fine but when I triggered the audio in the app, it gave a failure: "Speech initialization error: 2147483665". You need hardware to test the TTS.

So use your iPhone 5s or better. Attach it to your mac and set that as the target in Xcode.
Do a single page iOS project with a single text area and a button in the center. 
Wire the text area to a outlet so you have the text as a variable.
Wire the button to an action so you can trigger the TTS.
Import the necessary libraries:

import UIKit
import AVFoundation

Set two globals at the top of the View Controller so you have access to these two when you need them: the Speech Synthesizer (to acutally speak) and the Speech Utterance to hold what is to be spoken.

  let synth = AVSpeechSynthesizer()
     var myUtterance = AVSpeechUtterance(string: "")

In the action from the button you need to set the value of myUtterance with the string value from the text box: 

myUtterance = AVSpeechUtterance(string: textInput.text)
        myUtterance.rate = 0.3 // 0.0 -> 1.0
        myUtterance.volume = 8.0 // 0.0 -> 10.0
        myUtterance.pitchMultiplier = 0.7 // 0.5 -> 2.0

Of course with the rate, volume and pitch, you can set these values from sliders as well.

Next you need to know what voices you have the choice of - I looked around the internet and found some objectiveC code that gave some suggestions and so I used println to print them all out. 

        var array_of_voices = AVSpeechSynthesisVoice.speechVoices()
        println("These are the voices: \(array_of_voices)")

This printed out the following useful list of the voices that are on my phone:

These are the voices: [
[AVSpeechSynthesisVoice 0x174012640] Language: ar-SA, [AVSpeechSynthesisVoice 0x174012be0] Language: en-ZA, [AVSpeechSynthesisVoice 0x1740124d0] Language: nl-BE, [AVSpeechSynthesisVoice 0x174012660] Language: en-AU, [AVSpeechSynthesisVoice 0x174012690] Language: th-TH, [AVSpeechSynthesisVoice 0x1740126a0] Language: de-DE, [AVSpeechSynthesisVoice 0x1740126c0] Language: en-US, [AVSpeechSynthesisVoice 0x1740126d0] Language: pt-BR, [AVSpeechSynthesisVoice 0x1740126b0] Language: pl-PL, [AVSpeechSynthesisVoice 0x174012670] Language: en-IE, [AVSpeechSynthesisVoice 0x1740126e0] Language: el-GR, [AVSpeechSynthesisVoice 0x174012700] Language: id-ID, [AVSpeechSynthesisVoice 0x174012710] Language: sv-SE, [AVSpeechSynthesisVoice 0x174012760] Language: tr-TR, [AVSpeechSynthesisVoice 0x174012770] Language: pt-PT, [AVSpeechSynthesisVoice 0x174012780] Language: ja-JP, [AVSpeechSynthesisVoice 0x174012790] Language: ko-KR, [AVSpeechSynthesisVoice 0x174012830] Language: hu-HU, [AVSpeechSynthesisVoice 0x174012680] Language: cs-CZ, [AVSpeechSynthesisVoice 0x174012c00] Language: da-DK, [AVSpeechSynthesisVoice 0x174012bf0] Language: es-MX, [AVSpeechSynthesisVoice 0x174012c40] Language: fr-CA, [AVSpeechSynthesisVoice 0x174012c10] Language: nl-NL, [AVSpeechSynthesisVoice 0x174012bb0] Language: fi-FI, [AVSpeechSynthesisVoice 0x174012c50] Language: es-ES, [AVSpeechSynthesisVoice 0x174012c60] Language: it-IT, [AVSpeechSynthesisVoice 0x174012c70] Language: he-IL, [AVSpeechSynthesisVoice 0x174012c80] Language: no-NO, [AVSpeechSynthesisVoice 0x174012c90] Language: ro-RO, [AVSpeechSynthesisVoice 0x174012ca0] Language: zh-HK, [AVSpeechSynthesisVoice 0x174012cb0] Language: zh-TW, [AVSpeechSynthesisVoice 0x174012cc0] Language: sk-SK, [AVSpeechSynthesisVoice 0x174012cd0] Language: zh-CN, [AVSpeechSynthesisVoice 0x174012ce0] Language: ru-RU, [AVSpeechSynthesisVoice 0x174013030] Language: en-GB, [AVSpeechSynthesisVoice 0x174013010] Language: fr-FR, [AVSpeechSynthesisVoice 0x174013080] Language: hi-IN]

I set the voice to be French because my default text is the homage to the Crazy Ones by Steve Jobs ("Here is to the crazy ones ...") and with the French accent "troublemakers" sounds so cool/funny/touching all at the same time. (The Jobs text is below.)

// myUtterance.voice = AVSpeechSynthesisVoice(language:"en-GB")
        // myUtterance.voice = AVSpeechSynthesisVoice(language:"en-AU")
        myUtterance.voice = AVSpeechSynthesisVoice(language:"fr-FR")

Optional - I added a slider with an outlet called "speakingrate" and put the resulting rate in a label under the slider and set the rate like this:

        speed_label.text = "Speed: \(speakingrate.value)"  
myUtterance.rate = speakingrate.value

then I asked it to speak:

        synth.speakUtterance( myUtterance)

Success!

The Text:

Here's to the crazy ones, the misfits, the rebels, the troublemakers, the round pegs in the square holes ... the ones who see things differently -- they're not fond of rules, and they have no respect for the status quo. ... You can quote them, disagree with them, glorify or vilify them, but the only thing you can't do is ignore them because they change things. ... They push the human race forward, and while some may see them as the crazy ones, we see genius, because the people who are crazy enough to think that they can change the world, are the ones who do.

Thursday, September 8, 2011

First post

Moodle categories are used for ordering the course listing! Of course!