-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathSpeechDetectionViewController.swift
More file actions
executable file
·146 lines (132 loc) · 5.25 KB
/
SpeechDetectionViewController.swift
File metadata and controls
executable file
·146 lines (132 loc) · 5.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import UIKit
import Speech
class SpeechDetectionViewController: UIViewController, SFSpeechRecognizerDelegate {
@IBOutlet weak var detectedTextLabel: UILabel!
@IBOutlet weak var colorView: UIView!
@IBOutlet weak var startButton: UIButton!
let audioEngine = AVAudioEngine()
let speechRecognizer: SFSpeechRecognizer? = SFSpeechRecognizer()
let request = SFSpeechAudioBufferRecognitionRequest()
var recognitionTask: SFSpeechRecognitionTask?
var isRecording = false
override func viewDidLoad() {
super.viewDidLoad()
self.requestSpeechAuthorization()
}
//MARK: - Colors
enum Color: String {
case Red, Orange, Yellow, Green, Blue, Purple, Black, Gray
var create: UIColor {
switch self {
case .Red:
return UIColor.red
case .Orange:
return UIColor.orange
case .Yellow:
return UIColor.yellow
case .Green:
return UIColor.green
case .Blue:
return UIColor.blue
case .Purple:
return UIColor.purple
case .Black:
return UIColor.black
case .Gray:
return UIColor.gray
}
}
}
//MARK: IBActions and Cancel
@IBAction func startButtonTapped(_ sender: UIButton) {
if isRecording == true {
cancelRecording()
isRecording = false
startButton.backgroundColor = UIColor.gray
} else {
self.recordAndRecognizeSpeech()
isRecording = true
startButton.backgroundColor = UIColor.red
}
}
func cancelRecording() {
recognitionTask?.finish()
recognitionTask = nil
// stop audio
request.endAudio()
audioEngine.stop()
audioEngine.inputNode.removeTap(onBus: 0)
}
//MARK: - Recognize Speech
func recordAndRecognizeSpeech() {
let node = audioEngine.inputNode
let recordingFormat = node.outputFormat(forBus: 0)
node.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { buffer, _ in
self.request.append(buffer)
}
audioEngine.prepare()
do {
try audioEngine.start()
} catch {
self.sendAlert(title: "Speech Recognizer Error", message: "There has been an audio engine error.")
return print(error)
}
guard let myRecognizer = SFSpeechRecognizer() else {
self.sendAlert(title: "Speech Recognizer Error", message: "Speech recognition is not supported for your current locale.")
return
}
if !myRecognizer.isAvailable {
self.sendAlert(title: "Speech Recognizer Error", message: "Speech recognition is not currently available. Check back at a later time.")
// Recognizer is not available right now
return
}
recognitionTask = speechRecognizer?.recognitionTask(with: request, resultHandler: { result, error in
if let result = result {
let bestString = result.bestTranscription.formattedString
var lastString: String = ""
for segment in result.bestTranscription.segments {
let indexTo = bestString.index(bestString.startIndex, offsetBy: segment.substringRange.location)
lastString = String(bestString[indexTo...])
}
self.checkForColorsSaid(resultString: lastString)
} else if let error = error {
self.sendAlert(title: "Speech Recognizer Error", message: "There has been a speech recognition error.")
print(error)
}
})
}
//MARK: - Check Authorization Status
func requestSpeechAuthorization() {
SFSpeechRecognizer.requestAuthorization { authStatus in
OperationQueue.main.addOperation {
switch authStatus {
case .authorized:
self.startButton.isEnabled = true
case .denied:
self.startButton.isEnabled = false
self.detectedTextLabel.text = "User denied access to speech recognition"
case .restricted:
self.startButton.isEnabled = false
self.detectedTextLabel.text = "Speech recognition restricted on this device"
case .notDetermined:
self.startButton.isEnabled = false
self.detectedTextLabel.text = "Speech recognition not yet authorized"
@unknown default:
return
}
}
}
}
//MARK: - UI / Set view color.
func checkForColorsSaid(resultString: String) {
guard let color = Color(rawValue: resultString) else { return }
colorView.backgroundColor = color.create
self.detectedTextLabel.text = resultString
}
//MARK: - Alert
func sendAlert(title: String, message: String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}