Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ringo-101 ios stt #36

Merged
merged 6 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions iOS/Ringo/Ringo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
945CF9842B67E1CE00396E4E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 945CF9832B67E1CE00396E4E /* Assets.xcassets */; };
945CF9872B67E1CE00396E4E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 945CF9852B67E1CE00396E4E /* LaunchScreen.storyboard */; };
945CF9902B69341800396E4E /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 945CF98F2B69341800396E4E /* SnapKit */; };
94FB0A6B2B858F66005A4915 /* TestSTTViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94FB0A6A2B858F66005A4915 /* TestSTTViewController.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand Down Expand Up @@ -72,6 +73,7 @@
945CF9832B67E1CE00396E4E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
945CF9862B67E1CE00396E4E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
945CF9882B67E1CE00396E4E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
94FB0A6A2B858F66005A4915 /* TestSTTViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestSTTViewController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -173,6 +175,7 @@
94470A942B71680100F0A942 /* SigninService.swift */,
940C25652B74EF4D00E069D0 /* FriendService.swift */,
94470A962B717DC300F0A942 /* ConnectionViewController.swift */,
94FB0A6A2B858F66005A4915 /* TestSTTViewController.swift */,
945603202B6D2F06002F4B33 /* Canvas.swift */,
945CF9832B67E1CE00396E4E /* Assets.xcassets */,
945CF9852B67E1CE00396E4E /* LaunchScreen.storyboard */,
Expand Down Expand Up @@ -276,6 +279,7 @@
945CF97B2B67E1CD00396E4E /* AppDelegate.swift in Sources */,
945603172B6AC2D3002F4B33 /* RecentsViewController.swift in Sources */,
940C25872B7A89AB00E069D0 /* WebRTCClient.swift in Sources */,
94FB0A6B2B858F66005A4915 /* TestSTTViewController.swift in Sources */,
945603232B6D31D9002F4B33 /* ContactsTableViewCell.swift in Sources */,
945CF97D2B67E1CD00396E4E /* SceneDelegate.swift in Sources */,
94470A932B7163E900F0A942 /* Model.swift in Sources */,
Expand Down
Binary file not shown.
9 changes: 8 additions & 1 deletion iOS/Ringo/Ringo/ConnectionViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class ConnectionViewController: UIViewController {
let translateBtn = UIButton()
let hangUpBtn = UIButton()

let randomNames = ["example2"]
let randomNames = ["example"]

override func viewDidLoad() {
super.viewDidLoad()
Expand Down Expand Up @@ -100,6 +100,7 @@ class ConnectionViewController: UIViewController {
translateBtn.invalidateIntrinsicContentSize()
translateBtn.configuration?.contentInsets = NSDirectionalEdgeInsets(top: 25, leading: 23, bottom: 25, trailing: 23)
translateBtn.layer.cornerRadius = 40
translateBtn.addTarget(self, action: #selector(pressedTransBtn), for: .touchUpInside)

hStack2.axis = .horizontal
hStack2.alignment = .center
Expand Down Expand Up @@ -137,6 +138,12 @@ class ConnectionViewController: UIViewController {
CallService.shared.webRTCClient.endCall()
dismiss(animated: true)
}

@objc func pressedTransBtn() {
let sttVC = TestSTTViewController()
sttVC.modalPresentationStyle = .automatic
present(sttVC, animated: true,completion: nil)
}

}
//MARK: - CollectionViewDelegate
Expand Down
2 changes: 2 additions & 0 deletions iOS/Ringo/Ringo/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSSpeechRecognitionUsageDescription</key>
<string>Speech recognition will be used to determine which words you speak into the device&apos;s microphone.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Need microphone access for use device&apos;s mic</string>
<key>UIApplicationSceneManifest</key>
Expand Down
2 changes: 1 addition & 1 deletion iOS/Ringo/Ringo/Screens/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ extension ViewController {
}
}
}
// MARK: - canvas 이용하기
// MARK:
extension ViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
Expand Down
198 changes: 198 additions & 0 deletions iOS/Ringo/Ringo/TestSTTViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
//
// TestSTTViewController.swift
// Ringo
//
// Created by 강진혁 on 2/21/24.
//

import UIKit
import SnapKit
import Speech

class TestSTTViewController: UIViewController, SFSpeechRecognizerDelegate {

private let speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "ko-KR"))!

private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?

private var recognitionTask: SFSpeechRecognitionTask?

private let audioEngine = AVAudioEngine()

var textView = UITextView()

var recordButton = UIButton()

override func viewDidLoad() {
super.viewDidLoad()

setUpView()
setUpValue()
setConstraints()
}

func setUpView() {
view.addSubview(textView)
view.addSubview(recordButton)
}

func setUpValue() {

view.backgroundColor = .systemBackground

textView.font = .systemFont(ofSize: 30)

recordButton.configuration = .plain()
recordButton.isEnabled = false
recordButton.addTarget(self, action: #selector(recordButtonTapped), for: .touchUpInside)
recordButton.setTitle("말하기", for: .disabled)
recordButton.titleLabel?.font = .systemFont(ofSize: 50)
}

func setConstraints() {
textView.snp.makeConstraints { make in
make.top.equalTo(view.safeAreaLayoutGuide)
make.leading.equalTo(view.safeAreaLayoutGuide)
make.trailing.equalTo(view.safeAreaLayoutGuide)
make.bottom.equalTo(recordButton.snp.top)
}
recordButton.snp.makeConstraints { make in
make.bottom.equalTo(view.safeAreaLayoutGuide).inset(30)
make.centerX.equalTo(view.center.x)
}
}

override public func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Configure the SFSpeechRecognizer object already
// stored in a local member variable.
speechRecognizer.delegate = self

// Make the authorization request.
SFSpeechRecognizer.requestAuthorization { authStatus in

// Divert to the app's main thread so that the UI
// can be updated.
OperationQueue.main.addOperation {
switch authStatus {
case .authorized:
self.recordButton.isEnabled = true
case .denied:
self.recordButton.isEnabled = false
self.recordButton.setTitle("User denied access to speech recognition", for: .disabled)

case .restricted:
self.recordButton.isEnabled = false
self.recordButton.setTitle("Speech recognition restricted on this device", for: .disabled)

case .notDetermined:
self.recordButton.isEnabled = false
self.recordButton.setTitle("Speech recognition not yet authorized", for: .disabled)

default:
self.recordButton.isEnabled = false
}
}
}
}

private func startRecording() throws {

// Cancel the previous task if it's running.
if let recognitionTask = recognitionTask {
recognitionTask.cancel()
self.recognitionTask = nil
}

// Configure the audio session for the app.
let audioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(.record, mode: .measurement, options: .duckOthers)
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
let inputNode = audioEngine.inputNode

// Create and configure the speech recognition request.
recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
guard let recognitionRequest = recognitionRequest else { fatalError("Unable to created a SFSpeechAudioBufferRecognitionRequest object") }
recognitionRequest.shouldReportPartialResults = true

// Keep speech recognition data on device
if #available(iOS 13, *) {
recognitionRequest.requiresOnDeviceRecognition = true
}

// Create a recognition task for the speech recognition session.
// Keep a reference to the task so that it can be canceled.
recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { result, error in
var isFinal = false

if let result = result {
// Update the text view with the results.
self.textView.text = result.bestTranscription.formattedString
isFinal = result.isFinal
}

if error != nil || isFinal {
// Stop recognizing speech if there is a problem.
self.audioEngine.stop()
inputNode.removeTap(onBus: 0)

self.recognitionRequest = nil
self.recognitionTask = nil

self.recordButton.isEnabled = true
self.recordButton.setTitle("말하기", for: [])
}
}

// Configure the microphone input.
let recordingFormat = inputNode.outputFormat(forBus: 0)
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer: AVAudioPCMBuffer, when: AVAudioTime) in
self.recognitionRequest?.append(buffer)
}

audioEngine.prepare()
try audioEngine.start()

// Let the user know to start talking.
textView.text = "(말해보세요)"
}

// MARK: SFSpeechRecognizerDelegate

public func speechRecognizer(_ speechRecognizer: SFSpeechRecognizer, availabilityDidChange available: Bool) {
if available {
recordButton.isEnabled = true
recordButton.setTitle("말하기", for: [])
} else {
recordButton.isEnabled = false
recordButton.setTitle("Recognition Not Available", for: .disabled)
}
}

// MARK: Interface Builder actions

@objc func recordButtonTapped() {
if audioEngine.isRunning {
audioEngine.stop()
recognitionRequest?.endAudio()
recordButton.isEnabled = false
recordButton.setTitle("Stopping", for: .disabled)
} else {
do {
try startRecording()
recordButton.setTitle("그만 말하기", for: [])
} catch {
recordButton.setTitle("Recording Not Available", for: [])
}
}
}

}
// MARK: - canvas 이용하기
import SwiftUI
@available(iOS 13.0.0, *)
struct TestSTTViewPreview: PreviewProvider {
static var previews: some View {
TestSTTViewController().toPreview()
}
}