Aaron
Aaron

Reputation: 1342

Convert AppleScript for speech to Swift

I would like to convert this AppleScript into Swift.

Where the input is a string (myText: String), and the output is the string being spoken at a variable speed (readingSpeed: Int).

AppleScript:

on run {input, parameters}
    say input using "Alex" speaking rate 540

    return input
end run

I had considered using SpeakCFString, but could not make it work.

Upvotes: 0

Views: 120

Answers (1)

bensnider
bensnider

Reputation: 3772

Two approaches here, one using a shell task to call out to say, and another using the NSSpeechSynthesizer class.

NSTask Implementation:

import Foundation

let input = Process.arguments[1..<Process.arguments.count].joinWithSeparator(" ")

let task = NSTask()
task.launchPath = "/usr/bin/say"
task.arguments = ["-v", "alex", input]

task.launch()
task.waitUntilExit()

print(input)
exit(task.terminationStatus)

NSSpeechSynthesizer implementation:

import Foundation
import AppKit

class Speaker {
    var synth: NSSpeechSynthesizer!
    var speaking: Bool {
        get {
            return synth.speaking
        }
    }

    init() {
        setupSynth(nil)
    }

    init(voice: String?) {
        setupSynth(voice)
    }

    func setupSynth(voice: String?) {
        var voice = voice
        if voice == nil {
            voice = NSSpeechSynthesizer.availableVoices()[0]
        }

        synth = NSSpeechSynthesizer(voice: voice)
    }

    func say(text: String) -> Bool {
        return synth.startSpeakingString(text)
    }
}

func say(text: String) -> Bool {
    let speaker = Speaker()

    if (speaker.say(text)) {
        let loop = NSRunLoop.currentRunLoop()
        let mode = loop.currentMode ?? NSDefaultRunLoopMode
        while loop.runMode(mode, beforeDate: NSDate(timeIntervalSinceNow: 0.1)) && speaker.speaking {}
        return true
    }
    return false
}

let input = Process.arguments[1..<Process.arguments.count].joinWithSeparator(" ")
say(input)
print(input)

Both of these you can run in the same way:

$ swift speak.swift hello world

Upvotes: 2

Related Questions