mirror of
https://github.com/jeremysrand/ListenerApp.git
synced 2024-11-28 15:49:58 +00:00
Connect up the speech forwarder to the new UI.
This commit is contained in:
parent
c5e6cc70a5
commit
dc3db26243
@ -8,7 +8,6 @@
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
9D5155F326A1EF7B0075EBC7 /* ListenerGSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D5155F226A1EF7B0075EBC7 /* ListenerGSApp.swift */; };
|
||||
9D5155F526A1EF7B0075EBC7 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D5155F426A1EF7B0075EBC7 /* ContentView.swift */; };
|
||||
9D5155F726A1EF7C0075EBC7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9D5155F626A1EF7C0075EBC7 /* Assets.xcassets */; };
|
||||
9D5155FA26A1EF7C0075EBC7 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9D5155F926A1EF7C0075EBC7 /* Preview Assets.xcassets */; };
|
||||
9D51560526A1EF7C0075EBC7 /* ListenerGSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D51560426A1EF7C0075EBC7 /* ListenerGSTests.swift */; };
|
||||
@ -52,7 +51,6 @@
|
||||
9D0DC15826F2E47A007EB92D /* ListenerGS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ListenerGS.entitlements; sourceTree = "<group>"; };
|
||||
9D5155EF26A1EF7B0075EBC7 /* ListenerGS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ListenerGS.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9D5155F226A1EF7B0075EBC7 /* ListenerGSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListenerGSApp.swift; sourceTree = "<group>"; };
|
||||
9D5155F426A1EF7B0075EBC7 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
9D5155F626A1EF7C0075EBC7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
9D5155F926A1EF7C0075EBC7 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
||||
9D5155FB26A1EF7C0075EBC7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
@ -142,7 +140,6 @@
|
||||
9DD67CEF2728F5B700243FC6 /* DestinationsView.swift */,
|
||||
9DCCDACB271FB87100F311DF /* GSDestinations.swift */,
|
||||
9DD8905F2772D3B20084A894 /* GSView.swift */,
|
||||
9D5155F426A1EF7B0075EBC7 /* ContentView.swift */,
|
||||
9D6ED239271E6BD600D773CD /* SpeechForwarder.swift */,
|
||||
9DD8905E27726C140084A894 /* ListenerGS Icon.pxm */,
|
||||
9D51566326A36F530075EBC7 /* BinUtils */,
|
||||
@ -375,7 +372,6 @@
|
||||
9D51565326A36B410075EBC7 /* yudpsocket.c in Sources */,
|
||||
9DD890602772D3B20084A894 /* GSView.swift in Sources */,
|
||||
9D51565226A36B410075EBC7 /* Result.swift in Sources */,
|
||||
9D5155F526A1EF7B0075EBC7 /* ContentView.swift in Sources */,
|
||||
9D6ED23A271E6BD600D773CD /* SpeechForwarder.swift in Sources */,
|
||||
9D5155F326A1EF7B0075EBC7 /* ListenerGSApp.swift in Sources */,
|
||||
9D51566526A36F6D0075EBC7 /* BinUtils.swift in Sources */,
|
||||
|
@ -1,46 +0,0 @@
|
||||
//
|
||||
// ContentView.swift
|
||||
// ListenerGS
|
||||
//
|
||||
// Created by Jeremy Rand on 2021-07-16.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Speech
|
||||
|
||||
struct ContentView: View {
|
||||
@StateObject private var speechForwarder = SpeechForwarder()
|
||||
// private var destinations: GSDestinations
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
TextField("IP Address", text: $speechForwarder.ipAddress) { isEditing in
|
||||
speechForwarder.isEditing = isEditing
|
||||
} onCommit: {
|
||||
speechForwarder.validate(destination: speechForwarder.ipAddress)
|
||||
}
|
||||
.padding()
|
||||
|
||||
ScrollView() {
|
||||
Text(speechForwarder.log)
|
||||
.multilineTextAlignment(.leading)
|
||||
}
|
||||
|
||||
Button("Listen") {
|
||||
speechForwarder.listen()
|
||||
}
|
||||
.padding()
|
||||
.background(speechForwarder.listening ? Color.red : Color.clear)
|
||||
.foregroundColor(speechForwarder.listening ? .black : .blue)
|
||||
.disabled(speechForwarder.listenEnabled == false)
|
||||
.frame(maxWidth: .infinity)
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ContentView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ContentView()
|
||||
}
|
||||
}
|
@ -43,19 +43,28 @@ private extension GSButtonStyle {
|
||||
|
||||
struct GSView: View {
|
||||
private let ipAddress : String
|
||||
@StateObject private var speechForwarder = SpeechForwarder()
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Button("\(Image(systemName: "desktopcomputer.and.arrow.down")) Connect to \(ipAddress)") {
|
||||
print("Clicked connect")
|
||||
Button(speechForwarder.connected ?
|
||||
"\(Image(systemName: "desktopcomputer.trianglebadge.exclamationmark")) Disconnect from \(ipAddress)" :
|
||||
"\(Image(systemName: "desktopcomputer.and.arrow.down")) Connect to \(ipAddress)") {
|
||||
if (speechForwarder.connected) {
|
||||
speechForwarder.disconnect()
|
||||
} else {
|
||||
speechForwarder.connect(destination: ipAddress)
|
||||
}
|
||||
}
|
||||
.disabled(false)
|
||||
.buttonStyle(GSButtonStyle())
|
||||
|
||||
Button("\(Image(systemName: "ear.and.waveform")) Listen and Send Text") {
|
||||
print("Clicked listen")
|
||||
Button(speechForwarder.listening ?
|
||||
"\(Image(systemName: "ear.trianglebadge.exclamationmark")) Stop Listening" :
|
||||
"\(Image(systemName: "ear.and.waveform")) Listen and Send Text") {
|
||||
speechForwarder.listen()
|
||||
}
|
||||
.disabled(true)
|
||||
.disabled(!speechForwarder.connected)
|
||||
.buttonStyle(GSButtonStyle())
|
||||
|
||||
Spacer()
|
||||
|
@ -19,7 +19,7 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>329</string>
|
||||
<string>358</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
|
@ -6,16 +6,13 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
import os
|
||||
import Speech
|
||||
|
||||
class SpeechForwarder : ObservableObject {
|
||||
@Published var listening = false
|
||||
@Published var listenEnabled = false
|
||||
@Published var log = ""
|
||||
@Published var ipAddress = ""
|
||||
@Published var connected = false
|
||||
private var textHeard = ""
|
||||
@Published var isEditing = false
|
||||
|
||||
let LISTEN_STATE_MSG = 1
|
||||
let LISTEN_TEXT_MSG = 2
|
||||
@ -31,30 +28,34 @@ class SpeechForwarder : ObservableObject {
|
||||
|
||||
private let audioEngine = AVAudioEngine()
|
||||
|
||||
func logError(message: String) {
|
||||
log.append("ERROR: " + message + "\n")
|
||||
}
|
||||
private let logger = Logger()
|
||||
|
||||
func logEvent(message: String) {
|
||||
log.append("EVENT: " + message + "\n")
|
||||
}
|
||||
|
||||
func validate(destination : String) {
|
||||
logEvent(message: "Attempting to connect to " + destination)
|
||||
func connect(destination : String) {
|
||||
logger.debug("Attempting to connect to \(destination)")
|
||||
client = TCPClient(address: destination, port: Int32(port))
|
||||
guard let client = client else { return }
|
||||
switch client.connect(timeout: 10) {
|
||||
case .success:
|
||||
listenEnabled = true
|
||||
logEvent(message: "Connected to " + destination)
|
||||
connected = true
|
||||
logger.debug("Connected to \(destination)")
|
||||
case .failure(let error):
|
||||
client.close()
|
||||
self.client = nil
|
||||
logError(message: String(describing: error))
|
||||
logger.error("Failed to connect to \(destination): \(String(describing: error))")
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func disconnect() {
|
||||
if (listening) {
|
||||
listen()
|
||||
}
|
||||
|
||||
guard let client = client else { return }
|
||||
client.close()
|
||||
connected = false
|
||||
}
|
||||
|
||||
func listen() {
|
||||
self.listening.toggle()
|
||||
if (self.listening) {
|
||||
@ -94,14 +95,14 @@ class SpeechForwarder : ObservableObject {
|
||||
break
|
||||
case .failure(let error):
|
||||
self.listening = false
|
||||
logError(message: String(describing: error))
|
||||
logger.error("Unable to send header: \(String(describing: error))")
|
||||
}
|
||||
}
|
||||
|
||||
if (self.listening) {
|
||||
do {
|
||||
try startRecording()
|
||||
logEvent(message: "Listening...")
|
||||
logger.debug("Started listening")
|
||||
}
|
||||
catch {
|
||||
self.listening = false
|
||||
@ -109,7 +110,7 @@ class SpeechForwarder : ObservableObject {
|
||||
}
|
||||
|
||||
if (!self.listening) {
|
||||
logEvent(message: "Listening stopped")
|
||||
logger.debug("Stopped listening")
|
||||
audioEngine.stop()
|
||||
recognitionRequest?.endAudio()
|
||||
switch (client.send(data: isListening())) {
|
||||
@ -117,7 +118,7 @@ class SpeechForwarder : ObservableObject {
|
||||
break
|
||||
case .failure(let error):
|
||||
self.listening = false
|
||||
logError(message: String(describing: error))
|
||||
logger.error("Failed to send header: \(String(describing: error))")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -147,11 +148,11 @@ class SpeechForwarder : ObservableObject {
|
||||
switch (client.send(data: pack("<hh\(stringToSend.count)s", [LISTEN_TEXT_MSG, stringToSend.count, stringToSend]))) {
|
||||
case .success:
|
||||
self.textHeard = latestText
|
||||
logEvent(message: "Sent \"" + stringToSend + "\"")
|
||||
logger.debug("Sent text \"\(stringToSend)\"")
|
||||
break
|
||||
case .failure(let error):
|
||||
self.listening = false
|
||||
logError(message: String(describing: error))
|
||||
logger.error("Failed to send text: \(String(describing: error))")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -200,9 +201,14 @@ class SpeechForwarder : ObservableObject {
|
||||
self.recognitionRequest = nil
|
||||
self.recognitionTask = nil
|
||||
self.listening = false
|
||||
self.logEvent(message: "Listening stopped")
|
||||
self.logger.debug("Stopped listening")
|
||||
guard let client = self.client else { return }
|
||||
client.send(data: self.isListening())
|
||||
switch (client.send(data: self.isListening())) {
|
||||
case .success:
|
||||
break
|
||||
case .failure(let error):
|
||||
self.logger.error("Failed to send header: \(String(describing: error))")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user