음성 인식 사용하기
24-07-08 TIL
Skip.tools
SwiftUI 를 사용해서, iPhone과 Android를 동시에 개발할 수 있는 tool
https://github.com/skiptools/skip
음성 인식 사용하기
-
Text To Speech
-
Speech To Text
-
Speech 프레임워크를 통해, 앱이 탭과 제스처를 보완하는 오디오 명령을 인식할 수 있음
-
음성을 텍스트로, 혹은 텍스트를 음성으로.
-
음성 인식 기능을 추가함으로써 앱을 누구나 쉽게 사용 할 수 있도록 함 (시각장애인 분들을 위한 앱 개발 가능)
-
마이크 액세스와 음성 인식 사용 권한 필요
Speech To Text App
Speech Framework의 AudioEngine Object 에 대해서 알아야 한다.
AVAudioEngine은 오디오 처리 그래프를 관리하는 객체로, 다양한 오디오 노드를 연결하여 오디오 신호를 처리합니다. 각 노드는 입력 및 출력이 있으며, 서로 연결되어 오디오 신호를 변환하거나 전달할 수 있습니다.
let audioEngine = AVAudioEngine()
let node = audioEngine.inputNode
// 오디오 입력 형식을 가져옴
let recordingFormat = node.outputFormat(forBus: 0)
// 입력 노드에서 오디오 버퍼를 설치하여 오디오 데이터를 캡처
node.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, time) in
// 오디오 데이터가 버퍼에 캡처될 때마다 호출되는 블록
print("Captured audio buffer")
}
// 오디오 엔진을 준비하고 시작
audioEngine.prepare()
do {
try audioEngine.start()
} catch {
print("Error starting audio engine: \(error)")
}
이에 대한 과정은 다음과 같이 수행된다.
1. AVAudioEngine 객체를 생성하고, 입력 노드를 가져옵니다.
2. 입력 노드의 오디오 형식을 가져옵니다.
3. installTap 메서드를 사용하여 입력 노드에 오디오 버퍼를 설치합니다. 이 버퍼는 오디오 데이터를 캡처하고, 이를 처리하기 위해 제공된 클로저 블록에 전달합니다.
4. 오디오 엔진을 준비하고 시작합니다.
node는 audioEngine의 입력 노드를 나타내며, 이는 오디오 입력 장치에서 오디오 데이터를 수신하고 이를 오디오 엔진 내의 다른 노드로 전달하는 역할을 합니다. 이를 통해 실시간 오디오 데이터 캡처 및 처리가 가능합니다.
func startRecording() {
// 초기화 메시지 설정
message = "Start Recording"
// 오디오 입력 노드 설정
let node = audioEngine.inputNode
// 음성 인식 요청 초기화
recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
// 부분 결과를 보고하도록 설정
recognitionRequest?.shouldReportPartialResults = true
// 녹음 형식 설정
let recordingFormat = node.outputFormat(forBus: 0)
// 오디오 버퍼 탭 설치
node.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, _) in
recognitionRequest?.append(buffer)
}
// 오디오 엔진 준비 및 시작
audioEngine.prepare()
do {
try audioEngine.start()
} catch {
return print(error)
}
// 음성 인식기 준비
guard let recognizeMe = SFSpeechRecognizer() else {
return
}
if !recognizeMe.isAvailable {
return
}
// 음성 인식 작업 시작
recognitionTask = speechRecognizer?.recognitionTask(with: recognitionRequest ?? SFSpeechAudioBufferRecognitionRequest.init(), resultHandler: { result, error in
if let result = result {
let transcribedString = result.bestTranscription.formattedString
message = transcribedString
} else if let error {
print(error)
}
})
}
정리하면,이 함수는 오디오 입력을 캡처하고 이를 실시간으로 음성 인식(recognitionRequest?.shouldReportPartialResults = true)하여 텍스트로 변환하는 것이다.
Speech To Text App 2 (음성 명령 기능)
이번에는 음성 인식 기능을 활용하여, 배경색을 바꿔보는 ‘음성 명령 기능’을 구현해보았다.
func checkSpokenCommand(commandString: String) {
switch commandString {
case "Purple":
newColor = .purple
case "Green":
newColor = .green
case "Yellow":
newColor = .yellow
default:
newColor = .white
}
}
commandString 이라는 String 을 받아, 배경색을 바꿔주는 함수이다. 음성 인식 함수에 Speech To Text 한 결과를 넣으면 될 것이다.
let transcribedString = result.bestTranscription.formattedString
message = transcribedString
checkSpokenCommand(commandString: transcribedString)
Text To Speech App
이번에는 텍스트를 음성으로 바꿔주는 기능을 구현해보았다.
Text To Speech App은 Speech To Text와는 달리, 사용자의 개인정보를 필요로 하지 않기 때문에 별도로 권한 설정은 필요하지 않다.
T T S 는 AVFoundation 을 필요로 한다.
import AVFoundation
let audio = AVSpeechSynthesizer()
AVSpeechSynthesizer
An object that produces synthesized speech from text utterances and enables monitoring or controlling of ongoing speech.
@State var convertText = AVSpeechUtterance(string: "")
AVSpeechUtterance
An object that encapsulates the text for speech synthesis and parameters that affect the speech.
speech 로 변환할 텍스트를 AVSpeechUtterance 객체로 초기화 한다.
그리고 rate 프로퍼티를 통해 피치도 조정 가능하다.
var rate: Float { get set }
그리고 AVSpeechUtterance 를 받는 speakc method 를 통해 TTS를 실행한다.
func speak(_ utterance: AVSpeechUtterance)
아래 링크를 통해 iOS 디바이스에서 지원하는 다양한 목소리, 언어를 지원하는 identifier를 확인할 수 있다.
List of AVSpeechSynthesisVoice.speechVoices() on iOS Device
그리고 아래와 같은 방법으로 사용한다.
let voice = AVSpeechSynthesisVoice(identifier: "com.apple.ttsbundle.siri_female_en-AU_compact")
convertText.voice = voice
이렇게 음성 인식을 하는 방법에 대해서 알아보았다.