import Foundation /// PTT / wake-word path. Mirrors `feature/voice/SpeechFeature.kt`. /// /// **STUBBED on iOS.** The Android implementation drives /// `RecordOpImpl.startVoiceRecord(...)` plus an OPUS decoder that emits /// `speechAudio` PCM frames. The iOS counterpart sits on /// `JL_SpeechAIttsHandler` / `JL_SpeexManager`, which need explicit wiring /// against the SDK's stream callbacks. Until that path is implemented: /// /// - `start(...)` / `stop(...)` invoke the completion with `false` + an /// explanatory message; /// - `isRecording()` returns `false`. /// /// The MethodChannel surface is preserved so the Dart layer (which already /// expects errors here on missing devices) sees a clean `SPEECH_START_ERR`. class SpeechFeature { static let voiceTypePcm = 0 static let voiceTypeSpeex = 1 static let voiceTypeOpus = 2 static let sampleRate8k = 8 static let sampleRate16k = 16 static let vadWayDevice = 0 static let vadWaySdk = 1 static let reasonNormal = 0 static let reasonStop = 1 weak var server: JieliHomeServer? init(server: JieliHomeServer) { self.server = server } func isRecording(address: String?) -> Bool { false } func start( address: String?, voiceType: Int, sampleRate: Int, vadWay: Int, completion: @escaping (Bool, String?) -> Void ) { // TODO: wire to JL_SpeechAIttsHandler / JL_SpeexManager. completion(false, "speech.start not yet implemented on iOS") } func stop( address: String?, reason: Int, completion: @escaping (Bool, String?) -> Void ) { completion(false, "speech.stop not yet implemented on iOS") } func detach() { // No resources held while stubbed. } }