





















@@ -0,0 +1,100 @@
1+import Foundation
2+import OpenClawKit
3+import Speech
4+5+enum TalkSpeechLocale {
6+static let storageKey = "talk.speechLocale"
7+static let automaticID = "auto"
8+static let fallbackLocaleID = "en-US"
9+10+struct Option: Identifiable {
11+let id: String
12+let label: String
13+}
14+15+static func supportedOptions(
16+ supportedLocales: Set<Locale> = SFSpeechRecognizer.supportedLocales()
17+) -> [Option] {
18+var seen = Set<String>()
19+let dynamic: [Option] = supportedLocales
20+.compactMap { locale in
21+let id = self.canonicalID(locale.identifier)
22+guard seen.insert(id).inserted else { return nil }
23+return Option(id: id, label: self.friendlyName(for: locale))
24+}
25+.sorted { (lhs: Option, rhs: Option) in
26+ lhs.label.localizedCaseInsensitiveCompare(rhs.label) == .orderedAscending
27+}
28+return [Option(id: self.automaticID, label: "Automatic")] + dynamic
29+}
30+31+static func resolvedLocaleID(
32+ localSelection: String?,
33+ gatewaySelection: String?,
34+ deviceLocaleID: String = Locale.autoupdatingCurrent.identifier,
35+ fallbackLocaleID: String = Self.fallbackLocaleID,
36+ supportedLocaleIDs: Set<String>
37+) -> String? {
38+TalkConfigParsing.resolvedSpeechRecognitionLocaleID(
39+ preferredLocaleIDs: [
40+TalkConfigParsing.normalizedExplicitSpeechLocaleID(localSelection),
41+TalkConfigParsing.normalizedExplicitSpeechLocaleID(gatewaySelection),
42+ deviceLocaleID,
43+],
44+ fallbackLocaleID: fallbackLocaleID,
45+ supportedLocaleIDs: supportedLocaleIDs)
46+}
47+48+static func makeRecognizer(
49+ localSelection: String?,
50+ gatewaySelection: String?,
51+ supportedLocales: Set<Locale> = SFSpeechRecognizer.supportedLocales()
52+) -> (recognizer: SFSpeechRecognizer?, localeID: String?) {
53+let supportedIDs = Set(supportedLocales.map(\.identifier))
54+guard let localeID = self.resolvedLocaleID(
55+ localSelection: localSelection,
56+ gatewaySelection: gatewaySelection,
57+ supportedLocaleIDs: supportedIDs)
58+else {
59+let recognizer = SFSpeechRecognizer()
60+return (recognizer, recognizer?.locale.identifier)
61+}
62+63+if let recognizer = SFSpeechRecognizer(locale: Locale(identifier: localeID)) {
64+return (recognizer, localeID)
65+}
66+67+let recognizer = SFSpeechRecognizer()
68+return (recognizer, recognizer?.locale.identifier)
69+}
70+71+static func normalizedExplicitLocaleID(_ raw: String?) -> String? {
72+TalkConfigParsing.normalizedExplicitSpeechLocaleID(raw, automaticID: self.automaticID)
73+}
74+75+private static func normalizedLocaleID(_ raw: String?) -> String? {
76+TalkConfigParsing.normalizedSpeechLocaleID(raw)
77+}
78+79+private static func canonicalID(_ raw: String) -> String {
80+ raw.replacingOccurrences(of: "_", with: "-")
81+}
82+83+private static func friendlyName(for locale: Locale) -> String {
84+let id = self.canonicalID(locale.identifier)
85+let cleanLocale = Locale(identifier: id)
86+if let langCode = cleanLocale.language.languageCode?.identifier,
87+let lang = cleanLocale.localizedString(forLanguageCode: langCode),
88+let regionCode = cleanLocale.region?.identifier,
89+let region = cleanLocale.localizedString(forRegionCode: regionCode)
90+{
91+return "\(lang) (\(region))"
92+}
93+if let langCode = cleanLocale.language.languageCode?.identifier,
94+let lang = cleanLocale.localizedString(forLanguageCode: langCode)
95+{
96+return lang
97+}
98+return cleanLocale.localizedString(forIdentifier: id) ?? id
99+}
100+}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。