From: liangzhenying <867174124@qq.com>
Date: Mon, 29 Dec 2025 08:57:08 +0000 (+0800)
Subject: 骨传导完善
X-Git-Tag: 1.0.2~15
X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=714c3e8bba533939048d0c38541b6130293e6fd9;p=mirrors%2FShenYin.git
骨传导完善
---
diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCBleManager.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCBleManager.swift
index 15b9722..21420f4 100644
--- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCBleManager.swift
+++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCBleManager.swift
@@ -125,13 +125,13 @@ extension DCBleManager{
DCLogger.debug("æå¼AI对è¯")
case 0x02:
DCLogger.debug("å
³éAI对è¯")
- DCChat.shared.stopChat()
+// DCChat.shared.stopChat()
case 0x03:
DCLogger.debug("æå¼è³æºå½é³")
- DCBleRecord.shared.start()
+// DCBleRecord.shared.start(type: 0x00)
case 0x04:
DCLogger.debug("å
³éè³æºå½é³")
- DCBleRecord.shared.stop()
+// DCBleRecord.shared.stop()
default:
break
}
diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCBleRecord.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCBleRecord.swift
index 48ef04b..55820d3 100644
--- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCBleRecord.swift
+++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCBleRecord.swift
@@ -94,8 +94,8 @@ public class DCBleRecord {
}
}
-
- public func start(){
+ /// 0x00宿¶å½é³ï¼0x0céè¯å½é³
+ public func start(type:Int){
asrList = []
asrText = ""
@@ -104,8 +104,7 @@ public class DCBleRecord {
setupRecord()
let config = StarburstBleAsrConfig()
- config.type = 0x0c/// 0x00宿¶å½é³ï¼0x0céè¯å½é³
- //å¼å§å½é³
+ config.type = type
StarburstSdk.shared().startDeviceRecord(config)
}
diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCChat.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCChat.swift
index 34b409e..fdc5c88 100644
--- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCChat.swift
+++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCChat.swift
@@ -16,6 +16,17 @@ public class DCRole{
public var type:String = ""
/// è§è²
public var role:String = ""
+
+ public init(){
+
+ }
+
+ public init(sid: String, name: String, type: String, role: String) {
+ self.sid = sid
+ self.name = name
+ self.type = type
+ self.role = role
+ }
}
public class DCChat{
diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCChinse2En.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCChinse2En.swift
new file mode 100644
index 0000000..ba8b359
--- /dev/null
+++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCChinse2En.swift
@@ -0,0 +1,87 @@
+//
+// Untitled.swift
+// Example
+//
+// Created by liangshi on 2025/12/29.
+//
+
+import StarburstSdk
+
+public class DCChinse2En {
+ public static let shared = DCChinse2En()
+ /// è¯â¾ç¼ç ï¼é»è®¤ä¸ºæ®éè¯(zh-CN)ï¼auto_langèªå¨è¯å«
+ public var fromLanguage:String = "zh-CN"
+ /// ⽬æ è¯â¾ç¼ç ï¼é»è®¤ä¸ºè±è¯(en-US)ï¼auto_langèªå¨è¯å«
+ public var toLanguage:String = "en-US"
+ /// æ¯å¦ç¿»è¯ï¼é»è®¤falseãå¦æä¸ºtrueç¿»è¯æºè¯è¨åç®æ è¯è¨ä¸è½æ¯åä¸ç§è¯è¨
+ public var isTranslate = false
+ /// æ¯å¦è¿â¾Ttsï¼é»è®¤false
+ public var isTTs = false
+ /// é»è®¤pcm â½æpcm / ogg_opus / mp3
+ public var ttsFormat = "pcm"
+ /// è¯å«åè°
+ public var asrCallback:((String,Int)->Void)?
+ /// ç¿»è¯åè°
+ public var translateCallback:((String,Int)->Void)?
+ /// ç¿»è¯è¯é³åè°
+ public var translateDataCallback:((Data)->Void)?
+ /// ç¶æç åè°
+ public var codeCallback:((Int)->Void)?
+ /// ææ
+ public var interruptionCallBack:(()->Void)?
+ /// å½é³æä»¶åè°
+ public var filePathCallBack:((String?)->Void)?
+
+ var asrList : [(String,Int)] = []
+ var asrText = ""
+
+ var translateList : [(String,Int)] = []
+ var translateText = ""
+
+ public func start(){
+ let config = StarburstAsrConfig()
+ config.isTranslate = isTranslate
+ config.fromLanguage = fromLanguage
+ config.toLanguage = toLanguage
+ config.isTTs = isTTs
+ config.ttsFormat = ttsFormat
+ asrList = []
+ asrText = ""
+
+ translateList = []
+ translateText = ""
+
+ StarburstSdk.shared().startRecordAsr(config) {voiceData in
+ //DCLogger.debug("å½é³çé³é¢æµ = \(voiceData!)")
+ } recognizeText: {[weak self] model in
+ guard let self = self else {return}
+ guard let model = model else {return}
+
+ if let text = model.textResult,!text.isEmpty{
+// DCLogger.debug("asr = \(text)")
+ asrCallback?(text,model.definiteIndex)
+ }
+ if let translate = model.translateResult,let text = translate.text,!text.isEmpty{
+// DCLogger.debug("translate = \(text)")
+ translateCallback?(text,Int(translate.definiteIndex))
+ }
+ if let ttsData = model.ttsResult?.streamPiece {
+ if let data = Data(base64Encoded: ttsData){
+ translateDataCallback?(data)
+ }
+ }
+ } stateChange: {[weak self] code in
+ DCLogger.debug("ç¶ææ¹å",code)
+ self?.codeCallback?(code.rawValue)
+ } interruption: { [weak self] in
+ self?.interruptionCallBack?()
+ }
+ }
+ public func stop(){
+ StarburstSdk.shared().stopRecordAsr {[weak self] filePath in
+ DCLogger.debug("æä»¶å½é³ä¿åè·¯å¾ \(filePath ?? "")")
+ self?.filePathCallBack?(filePath)
+ }
+
+ }
+}
diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCPhoneRecord.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCPhoneRecord.swift
index 0d37199..6846441 100644
--- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCPhoneRecord.swift
+++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCPhoneRecord.swift
@@ -17,11 +17,13 @@ public class DCPhoneRecord {
/// æ¯å¦è¿â¾Ttsï¼é»è®¤false
public var isTTs = false
/// é»è®¤pcm â½æpcm / ogg_opus / mp3
- public var ttsFormat = "mp3"
+ public var ttsFormat = "pcm"
/// è¯å«åè°
public var asrCallback:((String)->Void)?
- /// è¯å«åè°
+ /// ç¿»è¯åè°
public var translateCallback:((String)->Void)?
+ /// ç¿»è¯è¯é³åè°
+ public var translateDataCallback:((Data)->Void)?
/// ç¶æç åè°
public var codeCallback:((Int)->Void)?
/// ææ
@@ -86,6 +88,11 @@ public class DCPhoneRecord {
translateCallback?(translateText)
}
+ if let ttsData = model.ttsResult?.streamPiece {
+ if let data = Data(base64Encoded: ttsData){
+ translateDataCallback?(data)
+ }
+ }
} stateChange: {[weak self] code in
DCLogger.debug("ç¶ææ¹å",code)
self?.codeCallback?(code.rawValue)
diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/SceneDelegate.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/SceneDelegate.swift
index 5c01cf8..17a75bf 100644
--- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/SceneDelegate.swift
+++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/SceneDelegate.swift
@@ -19,7 +19,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
guard let _ = (scene as? UIWindowScene) else { return }
App.shared.window = window
window?.rootViewController = UINavigationController(rootViewController: DeviceListVC())
- DCSdkManager.shared.initSdk()
+ DcSdkManager.shared.initSdk()
}
func sceneDidDisconnect(_ scene: UIScene) {
diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/ChatVC.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/ChatVC.swift
index 096d47c..d7985be 100644
--- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/ChatVC.swift
+++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/ChatVC.swift
@@ -55,14 +55,14 @@ class ChatVC: BaseVC {
}
}
func setupSDk(){
- DCChatManager.shared.chatNeedReloadData = {[weak self] in
+ DcChatManager.shared.chatNeedReloadData = {[weak self] in
guard let self = self else{return}
tableView.reloadData()
- if DCChatManager.shared.dataList.count > 0 {
- tableView.scrollToRow(at: IndexPath(row: DCChatManager.shared.dataList.count - 1, section: 0), at: .none, animated: true)
+ if DcChatManager.shared.dataList.count > 0 {
+ tableView.scrollToRow(at: IndexPath(row: DcChatManager.shared.dataList.count - 1, section: 0), at: .none, animated: true)
}
}
- DCChatManager.shared.codeCallback = { [weak self] code in
+ DcChatManager.shared.codeCallback = { [weak self] code in
guard let self = self else{return}
if code == 20001 {
self.recordBtn.isSelected = true
@@ -72,7 +72,7 @@ class ChatVC: BaseVC {
}
}
- DCChatManager.shared.finishCallback = { [weak self] path in
+ DcChatManager.shared.finishCallback = { [weak self] path in
guard let self = self else{return}
// self.recordBtn.isSelected = false
}
@@ -83,19 +83,19 @@ class ChatVC: BaseVC {
@objc func recordAction() {
self.recordBtn.isSelected = !self.recordBtn.isSelected
if self.recordBtn.isSelected {
- DCChatManager.shared.startChat()
+ DcChatManager.shared.startChat()
}
else{
stopAction()
}
}
func stopAction() {
- DCChatManager.shared.stopChat()
+ DcChatManager.shared.stopChat()
}
@objc func roleAction(){
let vc = RoleVC()
vc.didSelectedCallback = { role in
- DCChatManager.shared.role = role
+ DcChatManager.shared.role = role
}
navigationController?.pushViewController(vc, animated: true)
}
@@ -103,12 +103,12 @@ class ChatVC: BaseVC {
extension ChatVC:UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return DCChatManager.shared.dataList.count
+ return DcChatManager.shared.dataList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: ChatCell.reuseID, for: indexPath) as? ChatCell
- cell!.data = DCChatManager.shared.dataList[indexPath.row]
+ cell!.data = DcChatManager.shared.dataList[indexPath.row]
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/EarPhoneRecordVC.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/EarPhoneRecordVC.swift
index ce25d9e..6890241 100644
--- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/EarPhoneRecordVC.swift
+++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/EarPhoneRecordVC.swift
@@ -134,7 +134,7 @@ extension EarPhoneRecordVC{
DCBleRecord.shared.fromLanguage = fromLanguage
DCBleRecord.shared.toLanguage = toLanguage
DCBleRecord.shared.isTranslate = true
- DCBleRecord.shared.start()
+ DCBleRecord.shared.start(type: 0x00)
}
func stopAction(){
diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/tools/DCChatManager.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/tools/DCChatManager.swift
index e2443d0..3e5b65c 100644
--- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/tools/DCChatManager.swift
+++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/tools/DCChatManager.swift
@@ -1,5 +1,5 @@
//
-// DCChatManager.swift
+// DcChatManager.swift
// Example
//
// Created by liangshi on 2025/12/15.
@@ -41,8 +41,8 @@ public class ChatCellModel:NSObject,NSCoding {
}
-class DCChatManager:NSObject{
- static let shared = DCChatManager()
+class DcChatManager:NSObject{
+ static let shared = DcChatManager()
private var isTtsPlaying = false
private var audioData: Data?
@@ -176,7 +176,7 @@ class DCChatManager:NSObject{
// }
// }
}
-extension DCChatManager : PcmSoundDelegate {
+extension DcChatManager : PcmSoundDelegate {
func remaining(_ frames: UInt) {
DCLogger.debug("[frame:\(frames)]");
if (frames == 0) {
diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/tools/DCSdkManager.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/tools/DCSdkManager.swift
index 0e39f84..3a82873 100644
--- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/tools/DCSdkManager.swift
+++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/tools/DCSdkManager.swift
@@ -1,19 +1,18 @@
//
-// DCSdkManager.swift
+// DcSdkManager.swift
// Example
//
// Created by liangshi on 2025/12/19.
//
import DeepChordsSdk
-class DCSdkManager{
- static let shared = DCSdkManager()
+class DcSdkManager{
+ static let shared = DcSdkManager()
func initSdk(){
DeepChordsAiSdk.shared.initSDK()
-// DCRecordManager.shared.setupRecord()
- DCChatManager.shared.setupChat()
+ DcChatManager.shared.setupChat()
DCDevice.shared.eventCallback = { event in
switch event {
diff --git a/ShenYin/ShenYin.xcodeproj/project.pbxproj b/ShenYin/ShenYin.xcodeproj/project.pbxproj
index 1ea9a02..a2b618a 100644
--- a/ShenYin/ShenYin.xcodeproj/project.pbxproj
+++ b/ShenYin/ShenYin.xcodeproj/project.pbxproj
@@ -274,8 +274,10 @@
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = ShenYin/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = DeepChords;
+ INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "æ«æéè¿èç设å¤éè¦è·å¾æé";
INFOPLIST_KEY_NSCameraUsageDescription = "ä¿®æ¹ç¨æ·å¤´åãæäº¤æè§åé¦éè¦è®¿é®ç¸åä½¿ç¨æå头";
+ INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "å
许APP使ç¨å®ä½æ¹ä¾¿æ¥æ¾è³æº";
INFOPLIST_KEY_NSMicrophoneUsageDescription = "å½é³éè¦ä½¿ç¨éº¦å
é£";
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "ä¿®æ¹ç¨æ·å¤´åãæäº¤æè§åé¦éè¦è®¿é®ç¸å";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
@@ -283,13 +285,14 @@
INFOPLIST_KEY_UIMainStoryboardFile = Main;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = UIInterfaceOrientationPortrait;
+ INFOPLIST_KEY_UIUserInterfaceStyle = Light;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.2;
- PRODUCT_BUNDLE_IDENTIFIER = com.deepchords.app;
+ PRODUCT_BUNDLE_IDENTIFIER = com.deepchords.app1;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
@@ -324,8 +327,10 @@
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = ShenYin/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = DeepChords;
+ INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "æ«æéè¿èç设å¤éè¦è·å¾æé";
INFOPLIST_KEY_NSCameraUsageDescription = "ä¿®æ¹ç¨æ·å¤´åãæäº¤æè§åé¦éè¦è®¿é®ç¸åä½¿ç¨æå头";
+ INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "å
许APP使ç¨å®ä½æ¹ä¾¿æ¥æ¾è³æº";
INFOPLIST_KEY_NSMicrophoneUsageDescription = "å½é³éè¦ä½¿ç¨éº¦å
é£";
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "ä¿®æ¹ç¨æ·å¤´åãæäº¤æè§åé¦éè¦è®¿é®ç¸å";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
@@ -333,13 +338,14 @@
INFOPLIST_KEY_UIMainStoryboardFile = Main;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = UIInterfaceOrientationPortrait;
+ INFOPLIST_KEY_UIUserInterfaceStyle = Light;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.2;
- PRODUCT_BUNDLE_IDENTIFIER = com.deepchords.app;
+ PRODUCT_BUNDLE_IDENTIFIER = com.deepchords.app1;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
diff --git a/ShenYin/ShenYin/Info.plist b/ShenYin/ShenYin/Info.plist
index 16b05a5..82a0f3a 100644
--- a/ShenYin/ShenYin/Info.plist
+++ b/ShenYin/ShenYin/Info.plist
@@ -51,11 +51,5 @@
bluetooth-central
audio
- NSLocationWhenInUseUsageDescription
- å
许APP使ç¨å®ä½æ¹ä¾¿æ¥æ¾è³æº
- ITSAppUsesNonExemptEncryption
-
- UIUserInterfaceStyle
- Light
diff --git a/ShenYin/ShenYin/Launch/AppLaunch.swift b/ShenYin/ShenYin/Launch/AppLaunch.swift
index 3d52d87..a4b1540 100644
--- a/ShenYin/ShenYin/Launch/AppLaunch.swift
+++ b/ShenYin/ShenYin/Launch/AppLaunch.swift
@@ -15,7 +15,7 @@ class AppLaunch:NSObject{
IASignWithWeChat.shared.register()
-
+ CCCall.shared.start()
setupKeyboard()
loadCache()
LoginVM.fetchCountryList {result in
@@ -39,6 +39,5 @@ class AppLaunch:NSObject{
else{
App.shared.goToLogin()
}
-// App.shared.window?.rootViewController = ChatVC()
}
}
diff --git a/ShenYin/ShenYin/Launch/AppManager.swift b/ShenYin/ShenYin/Launch/AppManager.swift
index f86626e..1f3ae04 100644
--- a/ShenYin/ShenYin/Launch/AppManager.swift
+++ b/ShenYin/ShenYin/Launch/AppManager.swift
@@ -9,8 +9,6 @@ class App{
static let shared = App()
var window:UIWindow?
var isInBackground = false
- var isJoy = true
-
func topVC()->UIViewController!{
guard let vc = window?.rootViewController else{
@@ -19,20 +17,7 @@ class App{
}
return getTopViewController(from: vc)
}
- func preparePlay(){
- PcmSound.sharedInstance().stopAudioUnit()
- PcmSound.sharedInstance().cleanup()
- PcmSound.sharedInstance().setup(16000, withchannels: 1)
-
- let options: AVAudioSession.CategoryOptions = [.allowBluetooth]
- do {
- try AVAudioSession.sharedInstance().setCategory(.playback, options: [options])
- try AVAudioSession.sharedInstance().setActive(true)
- } catch {
- Logger.debug(error)
- }
- }
-
+
func willLogin(){
CacheManager.shared.user.tokenIsValid {[weak self] success in
guard let self = self else{return}
@@ -46,11 +31,11 @@ class App{
Logger.debug(DCFolder.user)
Logger.debug(DCFolder.record)
self.window?.rootViewController = BaseTC()
- if App.shared.isJoy {
+ if CCAiManager.isJoy {
JoySdkManager.shared.setupSdk()
}
else{
- DCSdkManager.shared.initSdk()
+ DcSdkManager.shared.initSdk()
}
}
func goToLogin(){
diff --git a/ShenYin/ShenYin/Sdk/CCAiManager.swift b/ShenYin/ShenYin/Sdk/CCAiManager.swift
new file mode 100644
index 0000000..518bb2d
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/CCAiManager.swift
@@ -0,0 +1,62 @@
+//
+// CCAiManager.swift
+// ShenYin
+//
+// Created by liangshi on 2025/12/25.
+//
+import JoyGemAI
+import DeepChordsSdk
+
+class CCAiManager {
+ static var isJoy = true
+
+ static func translate(text:String,from:String,to:String,finished:@escaping ((stream:String,finish:Bool)?)->Void){
+
+ if isJoy {
+ JoyGemAIManager.shared().translate(text, from: from, to: to) { result, finish in
+ finished((result,finish))
+ } error: { error in
+ finished(nil)
+ }
+ }
+ else{
+
+ }
+ }
+}
+extension CCAiManager{
+ static func preparePlayBlueTooth(){
+ PcmSound.sharedInstance().stopAudioUnit()
+ PcmSound.sharedInstance().cleanup()
+ PcmSound.sharedInstance().setup(16000, withchannels: 1)
+
+ let options: AVAudioSession.CategoryOptions = [.allowBluetooth]
+ do {
+ try AVAudioSession.sharedInstance().setCategory(.playback, options: [options])
+ try AVAudioSession.sharedInstance().setActive(true)
+ } catch {
+ Logger.debug(error)
+ }
+ }
+// static func preparePlay(){
+// PcmSound.sharedInstance().stopAudioUnit()
+// PcmSound.sharedInstance().cleanup()
+// PcmSound.sharedInstance().setup(16000, withchannels: 1)
+//
+// do {
+// try AVAudioSession.sharedInstance().setCategory(.playback)
+// try AVAudioSession.sharedInstance().setActive(true)
+// } catch {
+// Logger.debug(error)
+// }
+// }
+
+ static func stopPlay(){
+ PcmSound.sharedInstance().stopAudioUnit()
+ PcmSound.sharedInstance().cleanup()
+ }
+}
+
+
+
+
diff --git a/ShenYin/ShenYin/Sdk/CCBleManager.swift b/ShenYin/ShenYin/Sdk/CCBleManager.swift
index 4e13a15..1f62adc 100644
--- a/ShenYin/ShenYin/Sdk/CCBleManager.swift
+++ b/ShenYin/ShenYin/Sdk/CCBleManager.swift
@@ -71,13 +71,13 @@ extension CCBleManager:CBCentralManagerDelegate{
}
Logger.debug(peripheral)
- if App.shared.isJoy {
+ if CCAiManager.isJoy{
let mac = JoySdkManager.getMac(advertisementData) ?? ""
devices.append(DCPeripheral(device: peripheral,mac: mac))
discoverDeviceCallback?(devices)
}
else{
- let mac = DCSdkManager.getMac(advertisementData) ?? ""
+ let mac = DcSdkManager.getMac(advertisementData) ?? ""
devices.append(DCPeripheral(device: peripheral,mac: mac))
discoverDeviceCallback?(devices)
}
@@ -87,7 +87,7 @@ extension CCBleManager:CBCentralManagerDelegate{
stopScanDevice()
Logger.debug("èçå·²è¿æ¥ \(peripheral)")
peripheral.delegate = self
- if App.shared.isJoy {
+ if CCAiManager.isJoy{
peripheral.discoverServices([CBUUID(string: JoySdkManager.serviceUUID),CBUUID(string: OtaMananger.otaServiceUUId)]);
}
else{
@@ -101,8 +101,9 @@ extension CCBleManager:CBCentralManagerDelegate{
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
Logger.debug("èçå·²æå¼ \(peripheral)")
+ YLprogressHUD.showAutoHiden("èçå·²æå¼".l10n)
self.isConnetd = false
- if App.shared.isJoy {
+ if CCAiManager.isJoy{
DCBleManager.shared.centralManager(central, didDisconnectPeripheral: peripheral, error: nil)
}
NotificationManager.post(type: .deviceValidChange, objtect: nil)
@@ -121,7 +122,7 @@ extension CCBleManager: CBPeripheralDelegate {
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
- if App.shared.isJoy {
+ if CCAiManager.isJoy{
if (service.uuid.uuidString == JoySdkManager.serviceUUID) {
JoySdkManager.shared.peripheral(peripheral, didDiscoverCharacteristicsFor: service, error: error)
}
@@ -135,7 +136,7 @@ extension CCBleManager: CBPeripheralDelegate {
}
func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: (any Error)?) {
- if App.shared.isJoy {
+ if CCAiManager.isJoy{
if (characteristic.isNotifying == true && characteristic.service?.uuid.uuidString == JoySdkManager.serviceUUID && characteristic.uuid.uuidString == JoySdkManager.notifyUUID) {
Logger.debug("ç¹å¾ä½¿è½æå")
JoySdkManager.shared.bleConnected()
@@ -148,7 +149,7 @@ extension CCBleManager: CBPeripheralDelegate {
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
// Logger.debug("æ¶å°æ°æ® ===uUId ",characteristic.uuid)
- if App.shared.isJoy {
+ if CCAiManager.isJoy{
if OtaMananger.isOtadata(characteristic){
if let _ = characteristic.value,error == nil {
OtaMananger.shared.otaManager.peripheral(peripheral, didUpdateValueFor: characteristic)
@@ -189,7 +190,7 @@ extension CCBleManager{
// devices.append(DCPeripheral(device: item,mac: mac))
// }
// }
- if App.shared.isJoy {
+ if CCAiManager.isJoy{
centralManager.scanForPeripherals(withServices: [CBUUID(string: JoySdkManager.serviceUUID)],options: [CBCentralManagerScanOptionAllowDuplicatesKey : false])
}
else{
diff --git a/ShenYin/ShenYin/Sdk/CCCall.swift b/ShenYin/ShenYin/Sdk/CCCall.swift
new file mode 100644
index 0000000..fc9d089
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/CCCall.swift
@@ -0,0 +1,54 @@
+//
+// CCCall.swift
+// ShenYin
+//
+// Created by liangshi on 2025/12/29.
+//
+import CallKit
+import CoreTelephony
+
+class CCCall: NSObject, CXCallObserverDelegate {
+ static let shared = CCCall()
+
+ let callObserver = CXCallObserver()
+ var isInCall = false
+
+ override init() {
+ super.init()
+ checkInitialCallState()
+ start()
+ }
+
+ func start() {
+ callObserver.setDelegate(self, queue: nil)
+ }
+
+ func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) {
+ if call.hasEnded {
+ print("éè¯ç»æ")
+ isInCall = false
+ } else if call.isOnHold {
+ print("éè¯ä¿æä¸")
+ isInCall = true
+ } else if call.isOutgoing {
+ print("æ¨åºçµè¯")
+ isInCall = true
+ } else if call.hasConnected {
+ print("éè¯å·²æ¥é")
+ isInCall = true
+ }
+ }
+
+ private func checkInitialCallState() {
+ let callCenter = CTCallCenter()
+ if let calls = callCenter.currentCalls {
+ for call in calls {
+ if call.callState == CTCallStateDialing || call.callState == CTCallStateIncoming || call.callState == CTCallStateConnected {
+ print("æ£å¨å¬è¯ããã")
+ isInCall = true
+ return
+ }
+ }
+ }
+ }
+}
diff --git a/ShenYin/ShenYin/Sdk/CCPage.swift b/ShenYin/ShenYin/Sdk/CCPage.swift
new file mode 100644
index 0000000..75cc017
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/CCPage.swift
@@ -0,0 +1,67 @@
+//
+// CCVCManager.swift
+// ShenYin
+//
+// Created by liangshi on 2025/12/26.
+//
+
+class CCPage{
+ static func gotoChat(){
+ if CCAiManager.isJoy {
+ App.shared.goToPage(JoyChatVC())
+ }
+ else{
+ App.shared.goToPage(DcChatVC())
+ }
+ }
+ static func gotoFieldRecord(){
+ if CCAiManager.isJoy {
+ App.shared.goToPage(JoyXclyVC())
+ }
+ else{
+ App.shared.goToPage(DcXclyVC())
+ }
+ }
+ static func gotoCallRecord(){
+ if CCAiManager.isJoy {
+ if JoySdkManager.shared.callRecord.supportStereo{
+ App.shared.goToPage(JoyStereoCallVC())
+ }
+ else{
+ App.shared.goToPage(JoyCallingRecordVC())
+ }
+ }
+ else{
+// if JoySdkManager.shared.callRecord.supportStereo{
+// App.shared.goToPage(JoyStereoCallVC())
+// }
+// else{
+ App.shared.goToPage(DcCallingRecordVC())
+// }
+ }
+ }
+ static func gotoChinese2Enlgish(){
+ if CCAiManager.isJoy {
+ App.shared.goToPage(JoyChinese2EnglishVC())
+ }
+ else{
+ App.shared.goToPage(DcChinese2EnglishVC())
+ }
+ }
+ static func gotoTcty(){
+ if CCAiManager.isJoy {
+ App.shared.goToPage(JoyTctyVC())
+ }
+ else{
+ App.shared.goToPage(DcTctyVC())
+ }
+ }
+ static func gotoDialogTranslate(){
+ if CCAiManager.isJoy {
+ App.shared.goToPage(JoyDialogTranslateVC())
+ }
+ else{
+ App.shared.goToPage(DcDialogTranslateVC())
+ }
+ }
+}
diff --git a/ShenYin/ShenYin/Sdk/CCRole.swift b/ShenYin/ShenYin/Sdk/CCRole.swift
index 953f1b9..a11f84d 100644
--- a/ShenYin/ShenYin/Sdk/CCRole.swift
+++ b/ShenYin/ShenYin/Sdk/CCRole.swift
@@ -14,4 +14,23 @@ public class CCRole{
public var type:String = ""
/// è§è²
public var role:String = ""
+
+ public init(){
+
+ }
+ public init(sid: String, name: String, type: String, role: String) {
+ self.sid = sid
+ self.name = name
+ self.type = type
+ self.role = role
+ }
+
+ static var xiaoYin:CCRole{
+ let model = CCRole()
+ model.sid = "zh_female_tianmeitaozi_mars_bigtts"
+ model.name = "å°é³"
+ model.type = "default"
+ model.role = "test_xiaoyin"
+ return model
+ }
}
diff --git a/ShenYin/ShenYin/Sdk/CCSdkManager.swift b/ShenYin/ShenYin/Sdk/CCSdkManager.swift
deleted file mode 100644
index fe99743..0000000
--- a/ShenYin/ShenYin/Sdk/CCSdkManager.swift
+++ /dev/null
@@ -1,12 +0,0 @@
-//
-// CCSdkManager.swift
-// ShenYin
-//
-// Created by liangshi on 2025/12/25.
-//
-
-class CCSdkManager {
-
-
-
-}
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/DCChatVC.swift b/ShenYin/ShenYin/Sdk/DcSdk/DCChatVC.swift
deleted file mode 100644
index 51d58a7..0000000
--- a/ShenYin/ShenYin/Sdk/DcSdk/DCChatVC.swift
+++ /dev/null
@@ -1,218 +0,0 @@
-////
-//// DCChatVC.swift
-//// ShenYin
-////
-//// Created by liangshi on 2025/12/26.
-////
-//
-//import UIKit
-//import AVFAudio
-//import DeepChordsSdk
-//class DCChatVC:BaseVC{
-// let rightItem = ChatNavigationBarItem(frame: CGRect(x: 0, y: 0, width: 80, height: 44))
-// let roleItem = ChatRoleItem(frame: CGRect(x: 0, y: 0, width: 100, height: 44))
-//
-// let toolBar = ChatRecordBar()
-// let tableView = UITableView(frame: CGRectZero, style: .plain)
-// let headerView = ChatHeaderView(frame: CGRect(x: 0, y: 0, width: kScreenWid, height: 260))
-// let tipsLabel = UILabel()
-//
-// var roleList:[DCRole] = []
-//
-// deinit {
-// PcmSound.sharedInstance().stopAudioUnit()
-// PcmSound.sharedInstance().cleanup()
-// }
-//
-// override func viewDidLoad() {
-// super.viewDidLoad()
-// }
-// override func setupViews() {
-//
-// navBar.rightView.isHidden = true
-// navBar.addSubviews([roleItem,rightItem])
-// roleItem.yc.addTap(target: self, action: #selector(roleBtnAction))
-// rightItem.yc.addTap(target: self, action: #selector(rightBtnAction))
-//
-// tableView.backgroundColor = .clear
-// tableView.delegate = self
-// tableView.dataSource = self
-// tableView.estimatedRowHeight = 60
-// tableView.separatorStyle = .none
-// tableView.register(ChatCell.self, forCellReuseIdentifier: ChatCell.reuseID)
-// tableView.tableHeaderView = headerView
-//
-// view.addSubviews([tableView,toolBar,tipsLabel])
-// toolBar.delegate = self
-//
-// tipsLabel.do { v in
-// v.text = "å
容ç±AIçæï¼è¯·ä»ç»çå«".l10n
-// v.font = .regular(10)
-// v.textColor = .hexString("#919191")
-// }
-// }
-// override func setupLayout() {
-// rightItem.snp.makeConstraints { (m) in
-// m.top.equalTo(kNavTop)
-// m.bottom.equalToSuperview()
-// m.width.greaterThanOrEqualTo(80)
-// m.right.equalToSuperview()
-// }
-// roleItem.snp.makeConstraints { (m) in
-// m.top.equalTo(kNavTop)
-// m.bottom.equalToSuperview()
-// m.width.greaterThanOrEqualTo(80)
-// m.left.equalToSuperview().inset(48)
-// }
-// toolBar.snp.makeConstraints { make in
-// make.width.centerX.equalToSuperview()
-// make.height.equalTo(52)
-// make.bottom.equalToSuperview().inset(35)
-// }
-// tipsLabel.snp.makeConstraints { make in
-// make.top.equalTo(toolBar.snp.bottom).offset(4)
-// make.centerX.equalToSuperview()
-// }
-// tableView.snp.makeConstraints { make in
-// make.top.equalToSuperview().inset(kNavBtm)
-// make.left.right.equalToSuperview()
-// make.bottom.equalTo(toolBar.snp.top)
-// }
-// }
-// override func setupData() {
-// DCChatManager.shared.chatNeedReloadData = {[weak self] in
-// guard let self = self else{return}
-// tableView.reloadData()
-// if DCChatManager.shared.dataList.count > 0 {
-// tableView.scrollToRow(at: IndexPath(row: DCChatManager.shared.dataList.count - 1, section: 0), at: .none, animated: true)
-// }
-// }
-// DCChatManager.shared.codeCallback = { [weak self] code in
-// guard let self = self else{return}
-// if code == 20001 {
-// toolBar.recordBtn.state = .start
-// }
-// else if code == 20002 || code == 20003{
-// toolBar.recordBtn.state = .finish
-// }
-//
-// }
-// DCChatManager.shared.finishCallback = { [weak self] path in
-// guard let self = self else{return}
-// // self.recordBtn.isSelected = false
-// }
-//
-//
-// refreshData()
-// loadRoleList()
-// }
-// override func viewWillDisappear(_ animated: Bool) {
-// super.viewWillDisappear(animated)
-//
-// ///ç»æå¯¹è¯ï¼ä½å¹¶ä¸ä¼ç»æ¢æ£å¨ææ¾çå½é³
-// DCChatManager.shared.stopChat()
-//
-// }
-// override func viewDidAppear(_ animated: Bool) {
-// super.viewDidAppear(animated)
-// refreshData()
-// }
-// override func viewDidDisappear(_ animated: Bool) {
-// super.viewDidDisappear(animated)
-// ChatCache.shared.saveList(JoySdkManager.shared.chat.dataList)
-// }
-//
-// @objc func rightBtnAction() {
-// App.shared.goToPage(IntelligentVC())
-// }
-// @objc func roleBtnAction(){
-// if roleList.count == 0 {
-// loadRoleList()
-// return
-// }
-// let vc = RoleListVC(list: roleList, selectedModel: roleItem.role) {[weak self] model in
-// guard let self = self else{return}
-// roleItem.role = model
-// headerView.update(name: model.name, role: model.role)
-// JoyGemChatManager.shared().setSpeaker(model)
-// }
-// App.shared.goToPage(vc)
-// }
-// func refreshData(){
-// tableView.reloadData()
-// if JoySdkManager.shared.chat.dataList.count > 0 {
-// tableView.scrollToRow(at: IndexPath(row: JoySdkManager.shared.chat.dataList.count - 1, section: 0), at: .none, animated: true)
-// }
-// }
-// func loadRoleList(){
-// DCChatManager.shared.getVcSpeekerList {[weak self] speakers in
-// guard let self = self,speakers.count > 0 else{return}
-// self.roleList = speakers
-// self.roleList.insert(xiaoYinRole(), at: 0)
-//
-// var currentRole = roleList.first
-// if let cacheRole = RoleCache.get(){
-// for item in roleList{
-// if item.role == cacheRole {
-// currentRole = item
-// break
-// }
-// }
-// }
-// self.roleItem.role = currentRole
-// self.headerView.update(name: self.roleItem.role.name, role: self.roleItem.role.role)
-// JoyGemChatManager.shared().setSpeaker(self.roleItem.role)
-// }
-// }
-// func xiaoYinRole()->JoyGemSpeaker{
-// let model = JoyGemSpeaker()
-// model.sid = "zh_female_tianmeitaozi_mars_bigtts"
-// model.name = "å°é³"
-// model.type = "default"
-// model.role = "test_xiaoyin"
-// return model
-// }
-//}
-//
-//extension DCChatVC:ChatRecordBarDelegate{
-// func recordBarCancel(_ toolBar: ChatRecordBar) {
-// // JoyGemChatManager.shared().stopChat()
-// JoyGemChatManager.shared().stopSingleChat()
-// if let item = JoySdkManager.shared.chat.dataList.last,item.content.isEmpty{
-// JoySdkManager.shared.chat.dataList.removeLast()
-// refreshData()
-// }
-// }
-//
-// func recordBarStart(_ toolBar: ChatRecordBar) {
-// // let model = ChatCellModel()
-// // model.type = 1
-// // model.content = ""
-// // model.id = -1
-// // JoySdkManager.shared.dataList.append(model)
-// // refreshData()
-//
-// // JoyGemChatManager.shared().stopChat()
-// JoyGemChatManager.shared().startSingleChat()
-// DCChatManager.shared.startChat()
-// }
-//
-// func recordBarStop(_ toolBar: ChatRecordBar) {
-// JoyGemChatManager.shared().stopSingleChat()
-// }
-//}
-//
-//extension DCChatVC:UITableViewDelegate,UITableViewDataSource {
-// func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
-// return JoySdkManager.shared.chat.dataList.count
-// }
-//
-// func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-// let cell = ChatCell.cell(withTableView: tableView, indexPath: indexPath)
-// cell.data = JoySdkManager.shared.chat.dataList[indexPath.row]
-// return cell
-// }
-// func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
-//
-// }
-//}
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/BleManager.swift b/ShenYin/ShenYin/Sdk/DcSdk/DcBleManager.swift
similarity index 85%
rename from ShenYin/ShenYin/Sdk/DcSdk/BleManager.swift
rename to ShenYin/ShenYin/Sdk/DcSdk/DcBleManager.swift
index 3952660..dd6d19d 100644
--- a/ShenYin/ShenYin/Sdk/DcSdk/BleManager.swift
+++ b/ShenYin/ShenYin/Sdk/DcSdk/DcBleManager.swift
@@ -1,5 +1,5 @@
////
-//// BleManager.swift
+//// DcBleManager.swift
//// Example
////
//// Created by liangshi on 2025/11/24.
@@ -16,7 +16,7 @@
//import CoreBluetooth
//import DeepChordsSdk
//
-//class BleManager: NSObject {
+//class DcBleManager: NSObject {
// var discoverDeviceCallback: (([CBPeripheral]) -> Void)?
// var didConnectDeviceCallback: ((CBPeripheral) -> Void)?
// var disConnectDeviceCallback: ((CBPeripheral) -> Void)?
@@ -30,7 +30,7 @@
// centralManager = CBCentralManager(delegate: self, queue: nil)
// }
//
-// static let shared = BleManager()
+// static let shared = DcBleManager()
//
// func stopScanDevice() {
// centralManager.stopScan()
@@ -60,7 +60,7 @@
//// }
// }
//}
-//extension BleManager:CBCentralManagerDelegate{
+//extension DcBleManager:CBCentralManagerDelegate{
// func centralManagerDidUpdateState(_ central: CBCentralManager) {
// DCLogger.debug("èçç¶æ",central.state.rawValue)
// switch central.state {
@@ -100,28 +100,28 @@
//
// peripheral.delegate = self
// peripheral.discoverServices(nil);
-// DCBleManager.shared.centralManager(central, didConnect: peripheral)
+// DCDcBleManager.shared.centralManager(central, didConnect: peripheral)
// self.didConnectDeviceCallback?(peripheral)
// App.shared.window?.makeToast("èçå·²è¿æ¥")
// }
// func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
-// DCBleManager.shared.centralManager(central, didFailToConnect: peripheral, error: error)
+// DCDcBleManager.shared.centralManager(central, didFailToConnect: peripheral, error: error)
// }
// func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
// disConnectDeviceCallback?(peripheral)
-// DCBleManager.shared.centralManager(central, didDisconnectPeripheral: peripheral, error: nil)
+// DCDcBleManager.shared.centralManager(central, didDisconnectPeripheral: peripheral, error: nil)
// App.shared.window?.makeToast("èçå·²æå¼è¿æ¥")
// App.shared.window?.rootViewController = UINavigationController(rootViewController: DeviceListVC())
// }
//}
//
-//extension BleManager: CBPeripheralDelegate {
+//extension DcBleManager: CBPeripheralDelegate {
// func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
-// DCBleManager.shared.peripheral(peripheral, didDiscoverServices: error)
+// DCDcBleManager.shared.peripheral(peripheral, didDiscoverServices: error)
// }
//
// func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
-// DCBleManager.shared.peripheral(peripheral, didDiscoverCharacteristicsFor: service, error: error)
+// DCDcBleManager.shared.peripheral(peripheral, didDiscoverCharacteristicsFor: service, error: error)
// }
//
// func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: (any Error)?) {
@@ -129,7 +129,7 @@
// }
//
// func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
-// DCBleManager.shared.peripheral(peripheral, didUpdateValueFor: characteristic, error: error)
+// DCDcBleManager.shared.peripheral(peripheral, didUpdateValueFor: characteristic, error: error)
//
// }
//
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/DCChatManager.swift b/ShenYin/ShenYin/Sdk/DcSdk/DcChatManager.swift
similarity index 86%
rename from ShenYin/ShenYin/Sdk/DcSdk/DCChatManager.swift
rename to ShenYin/ShenYin/Sdk/DcSdk/DcChatManager.swift
index 005b2e8..ad5e4c4 100644
--- a/ShenYin/ShenYin/Sdk/DcSdk/DCChatManager.swift
+++ b/ShenYin/ShenYin/Sdk/DcSdk/DcChatManager.swift
@@ -1,5 +1,5 @@
//
-// DCChatManager.swift
+// DcChatManager.swift
// Example
//
// Created by liangshi on 2025/12/15.
@@ -20,8 +20,8 @@ import DeepChordsSdk
//};
-class DCChatManager:NSObject{
- static let shared = DCChatManager()
+class DcChatManager:NSObject{
+ static let shared = DcChatManager()
private var isTtsPlaying = false
private var audioData: Data?
@@ -44,25 +44,20 @@ class DCChatManager:NSObject{
public func startChat(){
DCChat.shared.startChat()
}
- public func getVcSpeekerList(finished:@escaping ([DCRole]?,Bool)->Void){
- DCChat.shared.getVcSpeekerList(finished: finished)
- }
-
- func preparePlay(){
- PcmSound.sharedInstance().cleanup()
- PcmSound.sharedInstance().setup(16000, withchannels: 1)
-
- var options: AVAudioSession.CategoryOptions = [.allowBluetooth]
- do {
- try AVAudioSession.sharedInstance().setCategory(.playback, options: [options])
- try AVAudioSession.sharedInstance().setActive(true)
- } catch {
- DCLogger.debug(error)
+ public func getVcSpeekerList(finished:@escaping ([DCRole]?)->Void){
+ DCChat.shared.getVcSpeekerList { list, success in
+ if success {
+ finished(list)
+ }
+ else{
+ finished(nil)
+ }
}
}
+
func setupChat(){
- preparePlay()
+ CCAiManager.preparePlayBlueTooth()
DCChat.shared.role = role
DCChat.shared.asrCallback = {[weak self] (text,index) in
guard let self = self else{return}
@@ -124,7 +119,7 @@ class DCChatManager:NSObject{
}
}
DCChat.shared.finishCallback = {[weak self] path in
- self?.preparePlay()
+ CCAiManager.preparePlayBlueTooth()
self?.finishCallback?(path)
}
@@ -155,7 +150,7 @@ class DCChatManager:NSObject{
// }
// }
}
-extension DCChatManager : PcmSoundDelegate {
+extension DcChatManager : PcmSoundDelegate {
func remaining(_ frames: UInt) {
DCLogger.debug("[frame:\(frames)]");
if (frames == 0) {
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/DcChinese2Enligsh.swift b/ShenYin/ShenYin/Sdk/DcSdk/DcChinese2Enligsh.swift
new file mode 100644
index 0000000..157223b
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/DcSdk/DcChinese2Enligsh.swift
@@ -0,0 +1,92 @@
+//
+// DcChinese2Enligsh.swift
+// ShenYin
+//
+// Created by liangshi on 2025/12/29.
+//
+
+import DeepChordsSdk
+
+class DcChinese2Enligsh:NSObject{
+ var dataList:[(Chinese2EnglishCellModel,Int)] = []
+ var startIndex = 0//è®°å½å¼å§å½é³ç次æ°ï¼ç¨äºåºåè¿åçæ°æ®
+
+ var stopCallback:(()->Void)?
+ var refreshDataCallback:(()->Void)?
+ override init(){
+ super.init()
+
+ }
+
+ func start(){
+ setupSdk()
+ startIndex += 100000
+
+ DCChinse2En.shared.fromLanguage = "auto_lang"
+ DCChinse2En.shared.toLanguage = "auto_lang"
+ DCChinse2En.shared.isTranslate = true
+ DCChinse2En.shared.isTTs = true
+ DCChinse2En.shared.start()
+ }
+
+ func stop(){
+ DCChinse2En.shared.stop()
+ }
+
+ func setupSdk(){
+ DCChinse2En.shared.asrCallback = { [weak self] (text,index) in
+ guard let self = self else{return}
+ Logger.debug("asr: \(text),index: \(index)")
+ let msg = dataList.firstIndex (where: { (str,idx) in
+ return idx == Int(index) + self.startIndex
+ })
+ if (msg == nil) {
+ dataList.append((Chinese2EnglishCellModel(send: text),Int(index) + startIndex))
+ } else {
+ let (item,_) = dataList[msg!]
+ item.send = text
+ }
+ //
+ // ///çå¬å°ä¸å¥è¯ç»æï¼èªå¨ç»æå½åå½é³
+ // if (model.definite == true) {
+ // stopEarRecord()
+ // }
+ refreshDataCallback?()
+ }
+ DCChinse2En.shared.translateCallback = { [weak self] (text,index) in
+ guard let self = self else{return}
+ Logger.debug("translate: \(text),index: \(index)")
+ let msg = dataList.firstIndex (where: { (str,idx) in
+ return idx == Int(index) + self.startIndex
+ })
+ if (msg == nil) {
+ dataList.append((Chinese2EnglishCellModel(response: text),Int(index) + startIndex))
+ } else {
+ let (item,_) = dataList[msg!]
+ item.response = text
+ }
+ refreshDataCallback?()
+ }
+ DCChinse2En.shared.translateDataCallback = { data in
+ PcmSound.sharedInstance().feed(data)
+ }
+ DCChinse2En.shared.codeCallback = { [weak self] code in
+ guard let self = self else{return}
+ if code == 20001 {
+ }
+ else if code == 20002 || code == 20003{
+ stopCallback?()
+ }
+ }
+ DCChinse2En.shared.filePathCallBack = { [weak self] path in
+ guard let self = self else{return}
+ }
+ }
+
+}
+
+extension DcChinese2Enligsh:PcmSoundDelegate{
+ func remaining(_ frames: UInt) {
+
+ }
+}
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/DCSdkManager.swift b/ShenYin/ShenYin/Sdk/DcSdk/DcSdkManager.swift
similarity index 56%
rename from ShenYin/ShenYin/Sdk/DcSdk/DCSdkManager.swift
rename to ShenYin/ShenYin/Sdk/DcSdk/DcSdkManager.swift
index 0ca4e8a..a0b4ff9 100644
--- a/ShenYin/ShenYin/Sdk/DcSdk/DCSdkManager.swift
+++ b/ShenYin/ShenYin/Sdk/DcSdk/DcSdkManager.swift
@@ -1,13 +1,13 @@
//
-// DCSdkManager.swift
+// DcSdkManager.swift
// Example
//
// Created by liangshi on 2025/12/19.
//
import DeepChordsSdk
-class DCSdkManager{
- static let shared = DCSdkManager()
+class DcSdkManager{
+ static let shared = DcSdkManager()
public var authCallback:((_ success:Bool)->Void)?
@@ -17,57 +17,80 @@ class DCSdkManager{
DCLogger.debug(code,msg)
guard let self = self else{return}
if code == 200{
- joyGemAuthSuccessCallback()
+ authSuccessCallback()
}
else{
- joyGemAuthFailedCallback()
+ authFailedCallback()
}
}
-// DCRecordManager.shared.setupRecord()
- DCChatManager.shared.setupChat()
+ DcChatManager.shared.setupChat()
+ /// aiäºä»¶åè°
+ /// 0x01(æå¼AI对è¯)
+ // 0x02(å
³éAI对è¯)
+ // 0x03(æå¼è³æºå½é³)
+ // 0x04(å
³éè³æºå½é³)
DCDevice.shared.eventCallback = { event in
switch event {
case 0x01:
- if let vc = App.shared.topVC() as? ChatVC {
+// 0x01(æå¼AI对è¯)
+ if let vc = App.shared.topVC() as? DcChatVC {
// vc.startRecord()
}else{
- App.shared.goToPage(ChatVC())
+ App.shared.goToPage(DcChatVC())
}
break
case 0x02:
+// 0x02(å
³éAI对è¯)
// if let vc = App.shared.topVC() as? ChatVC {
// // vc.startRecord()
// }else{
// App.shared.goToPage(ChatVC())
// }
+ DcChatManager.shared.stopChat()
break
case 0x03:
-// if let vc = App.shared.topVC() as? EarPhoneRecordVC {
-// // vc.startRecord()
-// }else{
-// App.shared.goToPage(EarPhoneRecordVC())
-// }
+ //0x03(æå¼è³æºå½é³)
+ if CCCall.shared.isInCall {
+ if let vc = App.shared.topVC() as? DcStereoCallVC {
+ vc.startRecord()
+ }
+ else{
+ App.shared.goToPage(DcStereoCallVC(autoStart: true))
+ DcXcly.shared.recordStart()
+ }
+ }
+ else{
+ if let vc = App.shared.topVC() as? DcXclyVC {
+ vc.startRecord()
+ }
+ else{
+ App.shared.goToPage(DcXclyVC(autoStart: true))
+ DcXcly.shared.recordStart()
+ }
+ }
break
case 0x04:
-// if let vc = App.shared.topVC() as? EarPhoneRecordVC {
-// // vc.startRecord()
-// }else{
-// App.shared.goToPage(EarPhoneRecordVC())
-// }
+ // 0x04(å
³éè³æºå½é³)
+ if let topVC = App.shared.topVC(), let vc = topVC as? DcXclyVC {
+ vc.stopRecord()
+ }
+ if let topVC = App.shared.topVC(), let vc = topVC as? DcCallingRecordVC {
+ vc.stopRecord()
+ }
break
default:
break
}
}
}
- func joyGemAuthFailedCallback() {
+ func authFailedCallback() {
Logger.debug("é´æå¤±è´¥")
YLprogressHUD.showAutoHiden("é´æå¤±è´¥")
}
- func joyGemAuthSuccessCallback() {
+ func authSuccessCallback() {
Logger.debug("é´ææå")
- App.shared.preparePlay()
+ CCAiManager.preparePlayBlueTooth()
DeviceCache.saveLastConnected(mac: CCBleManager.shared.connectPeripheral!.mac)
DeviceCache.shared.add(CCBleManager.shared.connectPeripheral!.device.identifier.uuidString, mac: CCBleManager.shared.connectPeripheral!.mac)
@@ -77,7 +100,7 @@ class DCSdkManager{
DeviceVM.updateOtaVersion()
}
}
-extension DCSdkManager{
+extension DcSdkManager{
static func getMac(_ dict:[String:Any])->String?{
if let advMsd = dict[CBAdvertisementDataManufacturerDataKey] as? Data {
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/DcTcty.swift b/ShenYin/ShenYin/Sdk/DcSdk/DcTcty.swift
new file mode 100644
index 0000000..cbf25be
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/DcSdk/DcTcty.swift
@@ -0,0 +1,93 @@
+//
+// Untitled.swift
+// ShenYin
+//
+// Created by liangshi on 2025/12/29.
+//
+
+import DeepChordsSdk
+
+class DcTcty:NSObject{
+ var messageList : [(String,UInt)] = []
+ var translateList : [(String,UInt)] = []
+ var recordFilePath : String?
+
+
+ var stopCallback:(()->Void)?
+ var refreshOriginCallback:((String)->Void)?
+ var refreshTranslateCallback:((String)->Void)?
+ var filePathCallback:((String)->Void)?
+
+ override init(){
+ super.init()
+
+
+ }
+
+ func setupSdk(){
+ DCPhoneRecord.shared.asrCallback = { [weak self] text in
+ guard let self = self else{return}
+ refreshOriginCallback?(text)
+ }
+ DCPhoneRecord.shared.translateCallback = { [weak self] text in
+ guard let self = self else{return}
+ refreshTranslateCallback?(text)
+ }
+ DCPhoneRecord.shared.translateDataCallback = { data in
+ PcmSound.sharedInstance().feed(data)
+ }
+ DCPhoneRecord.shared.codeCallback = { [weak self] code in
+ guard let self = self else{return}
+ if code == 20001 {
+ }
+ else if code == 20002 || code == 20003{
+ stopCallback?()
+ }
+ }
+ DCPhoneRecord.shared.filePathCallBack = { [weak self] path in
+ guard let self = self else{return}
+ recordFilePath = path
+ filePathCallback?(path ?? "")
+ }
+ }
+ func start(from:String,to:String){
+ setupSdk()
+ messageList.removeAll()
+ translateList.removeAll()
+
+ if Thread.isMainThread {
+ do {
+ try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [])
+ try AVAudioSession.sharedInstance().setActive(true)
+ } catch let error as NSError {
+ Logger.debug("An error occurred setting the audio session category: \(error.localizedDescription)")
+ }
+ } else {
+ DispatchQueue.main.sync {
+ do {
+ try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [])
+ try AVAudioSession.sharedInstance().setActive(true)
+ } catch let error as NSError {
+ Logger.debug("An error occurred setting the audio session category: \(error.localizedDescription)")
+ }
+ }
+ }
+
+ DCPhoneRecord.shared.fromLanguage = from
+ DCPhoneRecord.shared.toLanguage = to
+ DCPhoneRecord.shared.isTranslate = true
+ DCPhoneRecord.shared.isTTs = true
+ DCPhoneRecord.shared.start()
+ }
+
+ func stop(){
+ DCPhoneRecord.shared.stop()
+ }
+
+}
+
+extension DcTcty : PcmSoundDelegate {
+ func remaining(_ frames: UInt) {
+ Logger.debug("[frame:\(frames)]");
+ }
+}
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/DcThly.swift b/ShenYin/ShenYin/Sdk/DcSdk/DcThly.swift
new file mode 100644
index 0000000..47106fc
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/DcSdk/DcThly.swift
@@ -0,0 +1,79 @@
+//
+// DcThly.swift
+// ShenYin
+//
+// Created by liangshi on 2025/12/29.
+//
+
+import UIKit
+import DeepChordsSdk
+
+class DcThly:NSObject{
+ static let shared = DcThly()
+
+ var recordFinish:((String)->Void)?
+ var recordNeedReloadData:((String)->Void)?
+ var recordList : [(String,UInt)] = []
+ var recordText = ""
+ /// ç¶æç åè°
+ public var codeCallback:((Int)->Void)?
+ public var callRecordNotOnCall:(()->Void)?
+
+
+ override init() {
+ super.init()
+ setupSdk()
+ }
+ func setupSdk(){
+ DCBleRecord.shared.asrCallback = { [weak self] text in
+ guard let self = self else{return}
+ recordText = text
+ recordNeedReloadData?(text)
+ }
+ // DCBleRecord.shared.translateCallback = { [weak self] text in
+ // guard let self = self else{return}
+ // self.toTextView.text = text
+ // let range = NSMakeRange(toTextView.text.count - 1, 1)
+ // self.toTextView.scrollRangeToVisible(range)
+ // }
+ DCBleRecord.shared.codeCallback = { [weak self] code in
+ guard let self = self else{return}
+ codeCallback?(code)
+ }
+ DCBleRecord.shared.filePathCallBack = { [weak self] path in
+ guard let self = self else{return}
+ // self.recordBtn.isSelected = false
+ if recordText.isEmpty{
+ return
+ }
+ guard let path = path,path.isNotEmpty else{
+ return
+ }
+ guard let wavPath = DCFolder.recordFileResave(srcPath: path) else{return}
+ recordFinish?(wavPath)
+ }
+ }
+ func setRecordLanage(_ language:CCAiLanguage){
+ DCBleRecord.shared.fromLanguage = language.value
+ }
+ func recordStart(){
+ recordList.removeAll()
+ recordText = ""
+ setupSdk()
+ if !CCCall.shared.isInCall {
+ callRecordNotOnCall?()
+ return
+ }
+ Logger.debug("å¼å¯éè¯å½é³")
+ DCBleRecord.shared.start(type: 0x00 )
+ }
+ func recordResume(){
+ // JoyGemRecordManager.shared().resume()
+ }
+ func recordPause(){
+ // JoyGemRecordManager.shared().pause()
+ }
+ func recordStop(){
+ DCBleRecord.shared.stop()
+ }
+}
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/DcXcly.swift b/ShenYin/ShenYin/Sdk/DcSdk/DcXcly.swift
new file mode 100644
index 0000000..22e90e9
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/DcSdk/DcXcly.swift
@@ -0,0 +1,67 @@
+//
+// DcXcly.swift
+// ShenYin
+//
+// Created by liangshi on 2025/12/26.
+//
+
+import UIKit
+import DeepChordsSdk
+
+class DcXcly:NSObject{
+ static let shared = DcXcly()
+
+ var recordFinish:((String)->Void)?
+ var recordNeedReloadData:((String)->Void)?
+ var recordList : [(String,UInt)] = []
+ var recordText = ""
+ /// ç¶æç åè°
+ public var codeCallback:((Int)->Void)?
+
+ override init() {
+ super.init()
+ setupSdk()
+ }
+ func setupSdk(){
+ DCBleRecord.shared.asrCallback = { [weak self] text in
+ guard let self = self else{return}
+ recordText = text
+ recordNeedReloadData?(text)
+ }
+ DCBleRecord.shared.codeCallback = { [weak self] code in
+ guard let self = self else{return}
+ codeCallback?(code)
+ }
+ DCBleRecord.shared.filePathCallBack = { [weak self] path in
+ guard let self = self else{return}
+ // self.recordBtn.isSelected = false
+ if recordText.isEmpty{
+ return
+ }
+ guard let path = path,path.isNotEmpty else{
+ return
+ }
+ guard let wavPath = DCFolder.recordFileResave(srcPath: path) else{return}
+ recordFinish?(wavPath)
+ }
+ }
+ func setRecoordLanage(_ language:CCAiLanguage){
+ DCBleRecord.shared.fromLanguage = language.value
+ }
+ func recordStart(){
+ Logger.debug("å¼å¯å½é³")
+ recordList.removeAll()
+ recordText = ""
+ setupSdk()
+ DCBleRecord.shared.start(type: 0x0c )
+ }
+ func recordResume(){
+// JoyGemRecordManager.shared().resume()
+ }
+ func recordPause(){
+// JoyGemRecordManager.shared().pause()
+ }
+ func recordStop(){
+ DCBleRecord.shared.stop()
+ }
+}
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/VC/DcCallingRecordVC.swift b/ShenYin/ShenYin/Sdk/DcSdk/VC/DcCallingRecordVC.swift
new file mode 100644
index 0000000..536e48f
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/DcSdk/VC/DcCallingRecordVC.swift
@@ -0,0 +1,177 @@
+
+//
+// DcCallingRecordVC.swift
+// ShenYin
+//
+// Created by liangshi on 2025/8/6.
+//
+
+import UIKit
+import AVFAudio
+class DcCallingRecordVC:BaseVC{
+ let toolBar = FieldRecordBar()
+ let textView = UITextView()
+ let rhythView = RhythView()
+
+ var autoStart = false
+ var needSave = true
+ var bgEnter = false//æ¯å¦æ¯APPå¨åå°è¿å
¥è¿ä¸ªé¡µé¢ç
+
+ init(autoStart :Bool = false) {
+ self.autoStart = autoStart
+ super.init()
+ bgEnter = App.shared.isInBackground
+ setupSdk()
+ }
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ }
+ override func setupViews() {
+ navBar.title = "éè¯å½é³".l10n
+ navBar.backgroundColor = .white
+
+ toolBar.do { v in
+ v.delegate = self
+ v.hasRightItem = false
+ v.leftItem.language = AiLanguageCache.get(type: .thly) ?? .chinse
+ }
+
+ view.backgroundColor = .white
+
+ textView.do { v in
+ v.backgroundColor = .white
+ v.isEditable = false
+ v.font = .regular(14)
+ v.text = ""
+ v.textColor = .hexString("#121212")
+ v.contentInset = UIEdgeInsets(top: 0, left: 18, bottom: 0, right: 18)
+ }
+ view.addSubviews([rhythView,textView,toolBar])
+
+ }
+ override func setupLayout() {
+ rhythView.snp.makeConstraints { make in
+ make.width.centerX.equalToSuperview()
+ make.top.equalToSuperview().inset(kNavBtm)
+ make.height.equalTo(110)
+ }
+ toolBar.snp.makeConstraints { make in
+ make.width.centerX.equalToSuperview()
+ make.height.equalTo(120)
+ make.bottom.equalToSuperview().inset(20)
+ }
+ textView.snp.makeConstraints { make in
+ make.top.equalTo(rhythView.snp.bottom)
+ make.left.right.equalToSuperview()
+ make.bottom.equalTo(toolBar.snp.top)
+ }
+ }
+ override func setupData() {
+ if bgEnter {
+ textView.text = DcThly.shared.recordText
+ }
+ }
+ func setupSdk(){
+ DcThly.shared.recordFinish = {[weak self] path in
+ guard let self = self else { return }
+ if !needSave {
+ return
+ }
+ let v = PopTextField()
+ v.show()
+ v.cancelTap = {
+ App.shared.popPage()
+ }
+ v.okTap = { [weak self] text in
+ guard let self = self else{return}
+
+ let model = RecordDetailModel()
+ model.type = .phone
+ model.from = toolBar.leftItem.language
+ model.to = .english
+ model.name = text
+ model.path = path
+ model.duration = YLToos.getDuration(model.path)
+ model.origin = textView.text
+ model.translate = ""
+ App.shared.popPage(animated: false)
+ App.shared.goToPage(RecordDetailVC(record: model))
+ }
+ }
+ DcThly.shared.recordNeedReloadData = {[weak self] text in
+ guard let self = self else { return }
+ textView.text = text
+
+ let range = NSMakeRange(textView.text.count - 1, 1)
+ textView.scrollRangeToVisible(range)
+ }
+ //éè¦å®å
+// DcThly.shared.callRecordAutoFinish = {[weak self] in
+// guard let self = self else { return }
+// stopAction()
+// }
+ DcThly.shared.callRecordNotOnCall = {[weak self] in
+ guard let self = self else { return }
+ YLprogressHUD.showAutoHiden("æªå¤äºéè¯ç¶æ".l10n)
+ rhythView.reset()
+ toolBar.recordBtn.isSelected = false
+ toolBar.leftItem.alpha = 1
+ }
+
+ if autoStart{
+ startRecord()
+ }
+ }
+
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+ navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = false
+ }
+ override func viewDidDisappear(_ animated: Bool) {
+ super.viewDidDisappear(animated)
+ navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = true
+ }
+ override func navleftViewTapped() {
+ if toolBar.recordBtn.isSelected {
+ CustomAlert.showWith(title: "æç¤º".l10n, messgage: "å½åæ£å¨å½é³ï¼ç¡®å®æ¾å¼å½åå½é³åï¼".l10n, cancelCallback: {}) {[unowned self] in
+ self.rhythView.stopTimer()
+ self.needSave = false
+ DcThly.shared.recordStop()
+ self.navigationController?.popViewController(animated: true)
+ }
+ }
+ else{
+ super.navleftViewTapped()
+ }
+ }
+ func startRecord(){
+ toolBar.recordBtnAction()
+ }
+ func stopRecord(){
+ toolBar.recordBtnAction()
+ }
+}
+
+extension DcCallingRecordVC:FieldRecordBarDelegate{
+ func fieldRecordBar(_ bar: FieldRecordBar, languageChange language: CCAiLanguage) {
+ DcThly.shared.setRecordLanage(language)
+ AiLanguageCache.save(type: .thly, lan: language)
+ }
+
+ func fieldRecordBar(_ bar: FieldRecordBar, stateChange state: RecordSate) {
+ if state == .start {
+ textView.text = ""
+ rhythView.startTimer()
+ DcThly.shared.recordStart()
+ }
+ else if state == .stop{
+ stopAction()
+ }
+ }
+ func stopAction(){
+ rhythView.stopTimer()
+ DcThly.shared.recordStop()
+ toolBar.startAnimating()
+ }
+}
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/VC/DcChatVC.swift b/ShenYin/ShenYin/Sdk/DcSdk/VC/DcChatVC.swift
new file mode 100644
index 0000000..5b4b3f2
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/DcSdk/VC/DcChatVC.swift
@@ -0,0 +1,201 @@
+////
+//// DcChatVC.swift
+//// ShenYin
+////
+//// Created by liangshi on 2025/12/26.
+////
+//
+import UIKit
+import AVFAudio
+import DeepChordsSdk
+class DcChatVC:BaseVC{
+ let rightItem = ChatNavigationBarItem(frame: CGRect(x: 0, y: 0, width: 80, height: 44))
+ let roleItem = ChatRoleItem(frame: CGRect(x: 0, y: 0, width: 100, height: 44))
+
+ let toolBar = ChatRecordBar()
+ let tableView = UITableView(frame: CGRectZero, style: .plain)
+ let headerView = ChatHeaderView(frame: CGRect(x: 0, y: 0, width: kScreenWid, height: 260))
+ let tipsLabel = UILabel()
+
+ var roleList:[CCRole] = []
+
+ deinit {
+ CCAiManager.stopPlay()
+ }
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ }
+ override func setupViews() {
+
+ navBar.rightView.isHidden = true
+ navBar.addSubviews([roleItem,rightItem])
+ roleItem.yc.addTap(target: self, action: #selector(roleBtnAction))
+ rightItem.yc.addTap(target: self, action: #selector(rightBtnAction))
+
+ tableView.backgroundColor = .clear
+ tableView.delegate = self
+ tableView.dataSource = self
+ tableView.estimatedRowHeight = 60
+ tableView.separatorStyle = .none
+ tableView.register(ChatCell.self, forCellReuseIdentifier: ChatCell.reuseID)
+ tableView.tableHeaderView = headerView
+
+ view.addSubviews([tableView,toolBar,tipsLabel])
+ toolBar.delegate = self
+
+ tipsLabel.do { v in
+ v.text = "å
容ç±AIçæï¼è¯·ä»ç»çå«".l10n
+ v.font = .regular(10)
+ v.textColor = .hexString("#919191")
+ }
+ }
+ override func setupLayout() {
+ rightItem.snp.makeConstraints { (m) in
+ m.top.equalTo(kNavTop)
+ m.bottom.equalToSuperview()
+ m.width.greaterThanOrEqualTo(80)
+ m.right.equalToSuperview()
+ }
+ roleItem.snp.makeConstraints { (m) in
+ m.top.equalTo(kNavTop)
+ m.bottom.equalToSuperview()
+ m.width.greaterThanOrEqualTo(80)
+ m.left.equalToSuperview().inset(48)
+ }
+ toolBar.snp.makeConstraints { make in
+ make.width.centerX.equalToSuperview()
+ make.height.equalTo(52)
+ make.bottom.equalToSuperview().inset(35)
+ }
+ tipsLabel.snp.makeConstraints { make in
+ make.top.equalTo(toolBar.snp.bottom).offset(4)
+ make.centerX.equalToSuperview()
+ }
+ tableView.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(kNavBtm)
+ make.left.right.equalToSuperview()
+ make.bottom.equalTo(toolBar.snp.top)
+ }
+ }
+ override func setupData() {
+ DcChatManager.shared.chatNeedReloadData = {[weak self] in
+ guard let self = self else{return}
+ tableView.reloadData()
+ if DcChatManager.shared.dataList.count > 0 {
+ tableView.scrollToRow(at: IndexPath(row: DcChatManager.shared.dataList.count - 1, section: 0), at: .none, animated: true)
+ }
+ }
+ DcChatManager.shared.codeCallback = { [weak self] code in
+ guard let self = self else{return}
+ if code == 20001 {
+ toolBar.recordBtn.state = .start
+ }
+ else if code == 20002 || code == 20003{
+ toolBar.recordBtn.state = .finish
+ }
+
+ }
+ DcChatManager.shared.finishCallback = { [weak self] path in
+ guard let self = self else{return}
+ toolBar.recordBtn.state = .finish
+ }
+
+
+ refreshData()
+ loadRoleList()
+ }
+ override func viewWillDisappear(_ animated: Bool) {
+ super.viewWillDisappear(animated)
+ DcChatManager.shared.stopChat()
+ }
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+ refreshData()
+ }
+ override func viewDidDisappear(_ animated: Bool) {
+ super.viewDidDisappear(animated)
+ ChatCache.shared.saveList(DcChatManager.shared.dataList)
+ }
+
+ @objc func rightBtnAction() {
+ App.shared.goToPage(IntelligentVC())
+ }
+ @objc func roleBtnAction(){
+ if roleList.count == 0 {
+ loadRoleList()
+ return
+ }
+ let vc = RoleListVC(list: roleList, selectedModel: roleItem.role) {[weak self] model in
+ guard let self = self else{return}
+ roleItem.role = model
+ headerView.update(name: model.name, role: model.role)
+ DcChatManager.shared.role = DCRole(sid: model.sid, name: model.name, type: model.type, role: model.role)
+ }
+ App.shared.goToPage(vc)
+ }
+ func refreshData(){
+ tableView.reloadData()
+ if DcChatManager.shared.dataList.count > 0 {
+ tableView.scrollToRow(at: IndexPath(row: DcChatManager.shared.dataList.count - 1, section: 0), at: .none, animated: true)
+ }
+ }
+ func loadRoleList(){
+ DcChatManager.shared.getVcSpeekerList {[weak self] speakers in
+ guard let self = self,let speakers = speakers,speakers.count > 0 else{return}
+ self.roleList = speakers.map{CCRole(sid: $0.sid, name: $0.name, type: $0.type, role: $0.role)}
+ self.roleList.insert(CCRole.xiaoYin, at: 0)
+
+ var currentRole = roleList.first
+ if let cacheRole = RoleCache.get(){
+ for item in roleList{
+ if item.role == cacheRole {
+ currentRole = item
+ break
+ }
+ }
+ }
+ guard let currentRole = currentRole else{return}
+ self.roleItem.role = currentRole
+ self.headerView.update(name: self.roleItem.role.name, role: self.roleItem.role.role)
+ DcChatManager.shared.role = DCRole(sid: currentRole.sid, name: currentRole.name, type: currentRole.type, role: currentRole.role)
+ }
+ }
+
+}
+
+extension DcChatVC:ChatRecordBarDelegate{
+ func recordBarCancel(_ toolBar: ChatRecordBar) {
+// JoyGemChatManager.shared().stopSingleChat()
+ DcChatManager.shared.stopChat()
+ if let item = DcChatManager.shared.dataList.last,item.content.isEmpty{
+ DcChatManager.shared.dataList.removeLast()
+ refreshData()
+ }
+ }
+
+ func recordBarStart(_ toolBar: ChatRecordBar) {
+// JoyGemChatManager.shared().startSingleChat()
+ DcChatManager.shared.startChat()
+ }
+
+ func recordBarStop(_ toolBar: ChatRecordBar) {
+// JoyGemChatManager.shared().stopSingleChat()
+ DcChatManager.shared.stopChat()
+ }
+}
+
+extension DcChatVC:UITableViewDelegate,UITableViewDataSource {
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return DcChatManager.shared.dataList.count
+ }
+
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let cell = ChatCell.cell(withTableView: tableView, indexPath: indexPath)
+ cell.data = DcChatManager.shared.dataList[indexPath.row]
+ return cell
+ }
+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+
+ }
+}
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/VC/DcChinese2EnglishVC.swift b/ShenYin/ShenYin/Sdk/DcSdk/VC/DcChinese2EnglishVC.swift
new file mode 100644
index 0000000..0406d2f
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/DcSdk/VC/DcChinese2EnglishVC.swift
@@ -0,0 +1,142 @@
+//
+// Chinese2EnglishVC.swift
+// ShenYin
+//
+// Created by liangshi on 2025/8/6.
+//
+
+import UIKit
+import AVFAudio
+class DcChinese2EnglishVC:BaseVC{
+ let toolBar = RecordBar()
+ let tableView = UITableView(frame: CGRectZero, style: .plain)
+ let bg = UIImageView()
+ let sdk = DcChinese2Enligsh()
+ var dataList:[(Chinese2EnglishCellModel,Int)] = []
+
+ // deinit {
+ // PcmSound.sharedInstance().stopAudioUnit()
+ // PcmSound.sharedInstance().cleanup()
+ // }
+
+ override func setupViews() {
+ navBar.title = "ä¸è±äºè¯".l10n
+ navBar.rightView.isHidden = false
+ navBar.rightView.setImage(UIImage(named: "help_icon"), for: .normal)
+ view.addSubview(tableView)
+ view.addSubview(toolBar)
+ view.addSubview(bg)
+
+ toolBar.delegate = self
+ toolBar.isChienseEnglish = true
+ toolBar.leftItem.valueLabel.text = "å·¦è³".l10n
+ toolBar.rightItem.valueLabel.text = "å³è³".l10n
+
+ tableView.backgroundColor = .clear
+ tableView.delegate = self
+ tableView.dataSource = self
+ tableView.estimatedRowHeight = 60
+ tableView.separatorStyle = .none
+ tableView.register(Chinese2EnglishCell.self, forCellReuseIdentifier: Chinese2EnglishCell.reuseID)
+
+ bg.image = UIImage(named: "translate_bg")
+ }
+ override func setupLayout() {
+ toolBar.snp.makeConstraints { make in
+ make.width.centerX.equalToSuperview()
+ make.height.equalTo(120)
+ make.bottom.equalToSuperview().inset(20)
+ }
+ tableView.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(80)
+ make.left.right.equalToSuperview()
+ make.bottom.equalTo(toolBar.snp.top)
+ }
+ bg.snp.makeConstraints { make in
+ make.size.equalTo(90)
+ make.center.equalTo(tableView)
+ }
+ }
+ override func setupData() {
+ if TipsCache.needShow(type: .chinese2english) {
+ RecordTipsView(type: .chinese2english).show()
+ }
+ sdk.stopCallback = {[weak self] in
+ guard let self = self else{return}
+ toolBar.recordBtn.isSelected = false
+ }
+ sdk.refreshDataCallback = {[weak self] in
+ guard let self = self else{return}
+ dataList = sdk.dataList
+ refreshData()
+ }
+ }
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+ navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = false
+
+ PcmSound.sharedInstance().delegate = sdk
+ CCAiManager.preparePlayBlueTooth()
+ }
+ override func viewDidDisappear(_ animated: Bool) {
+ super.viewDidDisappear(animated)
+ navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = true
+ CCAiManager.preparePlayBlueTooth()
+ }
+ override func navleftViewTapped() {
+ if toolBar.recordBtn.isSelected {
+ self.sdk.stop()
+ // CustomAlert.showWith(title: "æç¤º".l10n, messgage: "å½åæ£å¨å½é³ï¼ç¡®å®æ¾å¼å½åå½é³å".l10n, cancelCallback: {}) {
+ // self.sdk.stop()
+ //// PcmSound.sharedInstance().stopAudioUnit()
+ //// PcmSound.sharedInstance().cleanup()
+ // super.navleftViewTapped()
+ // }
+ }
+ else{
+ super.navleftViewTapped()
+ }
+ }
+ override func navRightViewTapped() {
+ let tip = RecordTipsView(type: .chinese2english)
+ tip.show()
+ }
+ func refreshData(){
+ tableView.reloadData()
+ if dataList.count > 0 {
+ tableView.scrollToRow(at: IndexPath(row: dataList.count - 1, section: 0), at: .none, animated: true)
+ bg.isHidden = true
+ }
+ else{
+ bg.isHidden = false
+ }
+ }
+}
+extension DcChinese2EnglishVC:RecordBarDelegate{
+ func recordBarLanguageChange(_ bar: RecordBar) {
+
+ }
+ func recordBar(_ bar: RecordBar, stateChange state: RecordBarSate) {
+ if state == .start {
+ sdk.start()
+ }
+ else if state == .stop{
+ sdk.stop()
+ }
+ }
+}
+extension DcChinese2EnglishVC:UITableViewDelegate,UITableViewDataSource {
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return dataList.count
+ }
+
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let cell = Chinese2EnglishCell.cell(withTableView: tableView, indexPath: indexPath)
+ let (vallue,_) = dataList[indexPath.row]
+ cell.data = vallue
+ return cell
+ }
+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+
+ }
+}
diff --git a/ShenYin/ShenYin/UI/Home/Dialog/DialogTranlateVC.swift b/ShenYin/ShenYin/Sdk/DcSdk/VC/DcDialogTranslateVC.swift
similarity index 94%
rename from ShenYin/ShenYin/UI/Home/Dialog/DialogTranlateVC.swift
rename to ShenYin/ShenYin/Sdk/DcSdk/VC/DcDialogTranslateVC.swift
index 06ce7d9..fe50b07 100644
--- a/ShenYin/ShenYin/UI/Home/Dialog/DialogTranlateVC.swift
+++ b/ShenYin/ShenYin/Sdk/DcSdk/VC/DcDialogTranslateVC.swift
@@ -1,14 +1,14 @@
//
-// DialogTranslateVC.swift
+// Untitled.swift
// ShenYin
//
-// Created by liangshi on 2025/8/6.
+// Created by liangshi on 2025/12/29.
//
import UIKit
import JoyGemAI
import AVFoundation
-class DialogTranslateVC:BaseVC{
+class DcDialogTranslateVC:BaseVC{
let toolBar = DialogRecordBar()
var recordFilePath : String?
@@ -20,8 +20,7 @@ class DialogTranslateVC:BaseVC{
var tmpOtherList : [(String,UInt)] = []
var otherPcm = Data()
deinit {
- PcmSound.sharedInstance().stopAudioUnit()
- PcmSound.sharedInstance().cleanup()
+ CCAiManager.stopPlay()
}
override func viewDidLoad() {
super.viewDidLoad()
@@ -34,7 +33,7 @@ class DialogTranslateVC:BaseVC{
navBar.rightView.setImage(UIImage(named: "help_icon"), for: .normal)
toolBar.do { v in
-// v.backgroundColor = .clear
+ // v.backgroundColor = .clear
v.delegate = self
v.navBar = navBar
}
@@ -98,8 +97,7 @@ class DialogTranslateVC:BaseVC{
override func navleftViewTapped() {
JoyGemSIManager.shared().stop()
JoyGemSIDeviceManager.shared().stop()
- PcmSound.sharedInstance().stopAudioUnit()
- PcmSound.sharedInstance().cleanup()
+ CCAiManager.stopPlay()
super.navleftViewTapped()
}
@@ -112,7 +110,7 @@ class DialogTranslateVC:BaseVC{
}
}
-extension DialogTranslateVC:UITableViewDelegate,UITableViewDataSource {
+extension DcDialogTranslateVC:UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataList.count
}
@@ -127,7 +125,7 @@ extension DialogTranslateVC:UITableViewDelegate,UITableViewDataSource {
}
}
-extension DialogTranslateVC:DialogRecordBarDelegate{
+extension DcDialogTranslateVC:DialogRecordBarDelegate{
func recordBar(_ bar: DialogRecordBar, layoutChange: DialogRecordLayoutType) {
if layoutChange == .spolit{
splitView.isHidden = false
@@ -201,8 +199,8 @@ extension DialogTranslateVC:DialogRecordBarDelegate{
}
}
-extension DialogTranslateVC : JoyGemSIManagerDelegate {
-
+extension DcDialogTranslateVC : JoyGemSIManagerDelegate {
+
func siManagerStopped(_ manager: JoyGemSIManager, reason code: JoyGemRecordStopCode) {
if let model = dataList.last,model.send.isEmpty{
@@ -277,8 +275,8 @@ extension DialogTranslateVC : JoyGemSIManagerDelegate {
}
}
-extension DialogTranslateVC : JoyGemSIDeviceManagerDelegate {
-
+extension DcDialogTranslateVC : JoyGemSIDeviceManagerDelegate {
+
func siDeviceManagerStopped(_ manager: JoyGemSIDeviceManager, reason code: JoyGemRecordStopCode) {
@@ -355,7 +353,7 @@ extension DialogTranslateVC : JoyGemSIDeviceManagerDelegate {
}
-extension DialogTranslateVC : PcmSoundDelegate {
+extension DcDialogTranslateVC : PcmSoundDelegate {
func remaining(_ frames: UInt) {
Logger.debug("[frame:\(frames)]");
}
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/VC/DcStereoCallVC.swift b/ShenYin/ShenYin/Sdk/DcSdk/VC/DcStereoCallVC.swift
new file mode 100644
index 0000000..6fa9e3f
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/DcSdk/VC/DcStereoCallVC.swift
@@ -0,0 +1,264 @@
+//
+// Untitled 2.swift
+// ShenYin
+//
+// Created by liangshi on 2025/12/29.
+//
+
+import UIKit
+import AVFAudio
+class DcStereoCallVC:BaseVC{
+ let toolBar = FieldRecordBar()
+ let line = UIView()
+ let selfTextView = UITextView()
+ let otherTextView = UITextView()
+ private let selfLabel = DotLabel()
+ private let otherLabel = DotLabel()
+ let rhythView = RhythView()
+
+
+ var autoStart = false
+ var needSave = true
+ var bgEnter = false//æ¯å¦æ¯APPå¨åå°è¿å
¥è¿ä¸ªé¡µé¢ç
+
+ init(autoStart :Bool = false) {
+ self.autoStart = autoStart
+ super.init()
+ bgEnter = App.shared.isInBackground
+ setupSdk()
+ }
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ }
+ override func setupViews() {
+ navBar.title = "éè¯å½é³".l10n
+ navBar.backgroundColor = .white
+
+
+ toolBar.do { v in
+ v.delegate = self
+ v.hasRightItem = false
+ v.leftItem.language = AiLanguageCache.get(type: .thly) ?? .chinse
+ // v.backgroundColor = .red
+ }
+
+
+ view.backgroundColor = .white
+ // rhythView.backgroundColor = .blue
+ selfTextView.do { v in
+ v.backgroundColor = .white
+ v.isEditable = false
+ v.font = .regular(14)
+ v.text = ""
+ v.textColor = .hexString("#121212")
+ v.contentInset = UIEdgeInsets(top: 0, left: 13, bottom: 0, right: 13)
+ // v.backgroundColor = .green
+ }
+ otherTextView.do { v in
+ v.backgroundColor = .white
+ v.isEditable = false
+ v.font = .regular(14)
+ v.text = ""
+ v.textColor = .hexString("#121212")
+ v.contentInset = UIEdgeInsets(top: 0, left: 13, bottom: 0, right: 13)
+ // v.backgroundColor = .yellow
+ }
+ line.do { v in
+ v.backgroundColor = .hexString("#E9E9E9")
+ }
+ selfLabel.do { v in
+ v.label.text = "ä½ ï¼"
+ v.label.textColor = .hexString("#B9B9B9")
+ v.dot.backgroundColor = v.label.textColor
+ // v.backgroundColor = .red
+ }
+ otherLabel.do { v in
+ v.label.text = "对æ¹ï¼"
+ v.label.textColor = .hexString("#0092E1")
+ v.dot.backgroundColor = v.label.textColor
+ // v.backgroundColor = .red
+ }
+ view.addSubviews([rhythView,selfTextView,otherTextView,toolBar,line,selfLabel,otherLabel])
+
+ }
+ override func setupLayout() {
+ rhythView.snp.makeConstraints { make in
+ make.width.centerX.equalToSuperview()
+ make.top.equalToSuperview().inset(kNavBtm)
+ make.height.equalTo(110)
+ }
+ toolBar.snp.makeConstraints { make in
+ make.width.centerX.equalToSuperview()
+ make.height.equalTo(120)
+ make.bottom.equalToSuperview().inset(20)
+ }
+ selfLabel.snp.makeConstraints { make in
+ make.height.equalTo(16)
+ make.left.right.equalToSuperview()
+ make.top.equalToSuperview().inset(kNavBtm + 120)
+ }
+ selfTextView.snp.makeConstraints { make in
+ make.top.equalTo(selfLabel.snp.bottom)
+ make.left.right.equalToSuperview()
+ make.height.equalTo((kScreenHei - kNavBtm - 120 - 140 - 25 - 32)/2)
+ }
+ line.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(36)
+ make.height.equalTo(1)
+ make.top.equalTo(selfTextView.snp.bottom).offset(12)
+ }
+ otherLabel.snp.makeConstraints { make in
+ make.height.equalTo(16)
+ make.left.right.equalToSuperview()
+ make.top.equalTo(line.snp.bottom).offset(12)
+ }
+ otherTextView.snp.makeConstraints { make in
+ make.height.equalTo(selfTextView)
+ make.left.right.equalToSuperview()
+ make.top.equalTo(otherLabel.snp.bottom)
+ }
+
+ }
+ override func setupData() {
+ if bgEnter {
+ selfTextView.text = JoySdkManager.shared.callRecord.selfText
+ otherTextView.text = JoySdkManager.shared.callRecord.otherText
+ }
+ }
+
+ func setupSdk(){
+ JoySdkManager.shared.callRecord.recordFinish = {[weak self] path in
+ guard let self = self else { return }
+ if !needSave {
+ return
+ }
+ let v = PopTextField()
+ v.show()
+ v.cancelTap = {
+ App.shared.popPage()
+ }
+ v.okTap = { [weak self] text in
+ guard let self = self else{return}
+ gotoDetail(fileName: text, wavPath: path, language: toolBar.leftItem.language)
+ }
+ }
+ JoySdkManager.shared.callRecord.stereoNeedReloadData = {[weak self] (text,index) in
+ guard let self = self else { return }
+ if (index == 1) {
+ selfTextView.text = text
+ selfTextView.scrollToBottom()
+ } else if (index == 2) {
+ otherTextView.text = text
+ otherTextView.scrollToBottom()
+ }
+ }
+ JoySdkManager.shared.callRecord.callRecordAutoFinish = {[weak self] in
+ guard let self = self else { return }
+ stopAction()
+ }
+ JoySdkManager.shared.callRecord.callRecordNotOnCall = {[weak self] in
+ guard let self = self else { return }
+ YLprogressHUD.showAutoHiden("æªå¤äºéè¯ç¶æ".l10n)
+ rhythView.reset()
+ toolBar.recordBtn.isSelected = false
+ toolBar.leftItem.alpha = 1
+ }
+ if autoStart{
+ startRecord()
+ }
+ }
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+ navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = false
+ }
+ override func viewDidDisappear(_ animated: Bool) {
+ super.viewDidDisappear(animated)
+ navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = true
+ }
+ override func navleftViewTapped() {
+ if toolBar.recordBtn.isSelected {
+ CustomAlert.showWith(title: "æç¤º".l10n, messgage: "å½åæ£å¨å½é³ï¼ç¡®å®æ¾å¼å½åå½é³åï¼".l10n, cancelCallback: {}) {[unowned self] in
+ self.rhythView.stopTimer()
+ self.needSave = false
+ JoySdkManager.shared.callRecord.callRecordStop()
+ self.navigationController?.popViewController(animated: true)
+ }
+ }
+ else{
+ super.navleftViewTapped()
+ }
+ }
+ func startRecord(){
+ toolBar.recordBtnAction()
+ }
+ func stopRecord(){
+ toolBar.recordBtnAction()
+ }
+}
+
+extension DcStereoCallVC:FieldRecordBarDelegate{
+ func fieldRecordBar(_ bar: FieldRecordBar, languageChange language: CCAiLanguage) {
+ JoySdkManager.shared.callRecord.setCallRecoordLanage(language)
+ AiLanguageCache.save(type: .thly, lan: language)
+ }
+
+ func fieldRecordBar(_ bar: FieldRecordBar, stateChange state: RecordSate) {
+ if state == .start {
+ // selfMessageList.removeAll()
+ // otherMessageList.removeAll()
+ selfTextView.text = nil
+ otherTextView.text = nil
+ JoySdkManager.shared.callRecord.callRecordStart()
+ rhythView.startTimer()
+ }
+ else if state == .stop{
+ stopAction()
+ }
+ }
+ func stopAction(){
+ rhythView.stopTimer()
+ JoySdkManager.shared.callRecord.callRecordStop()
+ toolBar.startAnimating()
+ }
+ func gotoDetail( fileName:String,wavPath:String,language:CCAiLanguage){
+ let model = RecordDetailModel()
+ model.type = .phone
+ model.from = language
+ model.to = .english
+ model.name = fileName
+ model.path = wavPath
+ model.duration = YLToos.getDuration(model.path)
+ model.origin = "ä½ ï¼".l10n + "\n" + selfTextView.text + "\n\n" + "对æ¹ï¼".l10n + "\n" + otherTextView.text
+ model.translate = ""
+ App.shared.popPage(animated: false)
+ App.shared.goToPage(RecordDetailVC(record: model))
+ }
+}
+
+fileprivate class DotLabel:BaseView{
+ let dot = UIView()
+ let label = UILabel()
+
+ override func setupViews() {
+ addSubviews([dot,label])
+ dot.do { v in
+ v.yc.setCornerRadius(3)
+ v.backgroundColor = .hexString("#B9B9B9")
+ }
+ label.do { v in
+ v.font = .regular(12)
+ }
+ }
+ override func setupLayout() {
+ dot.snp.makeConstraints { make in
+ make.size.equalTo(6)
+ make.left.equalToSuperview().inset(18)
+ make.centerY.equalToSuperview()
+ }
+ label.snp.makeConstraints { make in
+ make.left.equalToSuperview().inset(28)
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(36)
+ }
+ }
+}
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/VC/DcTctyVC.swift b/ShenYin/ShenYin/Sdk/DcSdk/VC/DcTctyVC.swift
new file mode 100644
index 0000000..43fafb7
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/DcSdk/VC/DcTctyVC.swift
@@ -0,0 +1,155 @@
+//
+// Untitled.swift
+// ShenYin
+//
+// Created by liangshi on 2025/12/29.
+//
+
+import UIKit
+import AVFoundation
+class DcTctyVC:BaseVC{
+ let toolBar = RecordBar()
+ let textView = PlaceHolderTextView()
+ let translateTextView = PlaceHolderTextView()
+ let sdk = DcTcty()
+
+ deinit {
+ CCAiManager.stopPlay()
+ }
+ override func setupViews() {
+ view.addSubviews([toolBar,textView,translateTextView])
+ navBar.title = "åä¼ å¬è¯".l10n
+ navBar.rightView.isHidden = false
+ navBar.rightView.setImage(UIImage(named: "help_icon"), for: .normal)
+
+ toolBar.do { v in
+ v.backgroundColor = .clear
+ v.delegate = self
+ v.recordBtn.activeView.backgroundColor = .hexString("#F7F7F7")
+ v.leftItem.valueLabel.text = "ææº".l10n
+ v.leftItem.language = AiLanguageCache.get(type: .tscy_left) ?? .chinse
+ v.rightItem.language = AiLanguageCache.get(type: .tscy_right) ?? .english
+ }
+ view.backgroundColor = .hexString("#F7F7F7")
+
+ textView.do { v in
+ v.placeHolde = "æ¤å¤å°æ¾ç¤ºåæ".l10n
+ v.textView.textColor = .hexString("#666666")
+ }
+ translateTextView.do { v in
+ v.textView.textColor = .hexString("#121212")
+ v.placeHolde = "æ¤å¤å°æ¾ç¤ºè¯æ".l10n
+ v.bgView.yc.addgradientLayer(colors: [.hexString("#0092E1"),.hexString("#F7F7F7")], direction: .top2down,rect: CGRect(x: 0, y: 0, width: kScreenWid, height: (kScreenHei - kNavBtm - 120 - 10)/2))
+ v.bgView.alpha = 0.1
+ v.yc.setCorners(withRoundedRect: CGRect(x: 0, y: 0, width: kScreenWid, height: (kScreenHei - kNavBtm - 120 - 10)/2), roundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 20, height: 20))
+ }
+ }
+ override func setupLayout() {
+ toolBar.snp.makeConstraints { make in
+ make.width.centerX.equalToSuperview()
+ make.height.equalTo(120)
+ make.bottom.equalToSuperview().inset(20)
+ }
+ textView.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(80)
+ make.left.right.equalToSuperview()
+ make.height.equalTo((kScreenHei - kNavBtm - 120 - 10)/2)
+ }
+ translateTextView.snp.makeConstraints { make in
+ make.top.equalTo(textView.snp.bottom).offset(10)
+ make.left.right.equalToSuperview()
+ make.bottom.equalTo(toolBar.snp.top)
+ }
+ }
+ override func setupData() {
+ if TipsCache.needShow(type: .tongchuan) {
+ RecordTipsView(type: .tongchuan).show()
+ }
+
+ sdk.stopCallback = {[weak self] in
+ guard let self = self else{return}
+ toolBar.recordBtn.isSelected = false
+ }
+ sdk.refreshOriginCallback = {[weak self] text in
+ guard let self = self else{return}
+ textView.text = text
+ textView.textView.scrollToBottom()
+ }
+ sdk.refreshTranslateCallback = {[weak self] text in
+ guard let self = self else{return}
+ translateTextView.text = text
+ translateTextView.textView.scrollToBottom()
+ }
+ sdk.filePathCallback = { [weak self] path in
+ guard let self = self else{return}
+ guard let wavPath = DCFolder.recordFileResave(srcPath: path) else{return}
+ let v = PopTextField()
+ v.show()
+ v.cancelTap = {
+ App.shared.popPage()
+ }
+ v.okTap = { [weak self] text in
+ guard let self = self else{return}
+
+ let model = RecordDetailModel()
+ model.type = .translate
+ model.from = toolBar.leftItem.language
+ model.to = toolBar.rightItem.language
+ model.name = text
+ model.path = wavPath
+ model.duration = YLToos.getDuration(model.path)
+ model.origin = textView.text ?? ""
+ model.translate = translateTextView.text ?? ""
+ App.shared.popPage(animated: false)
+ App.shared.goToPage(RecordDetailVC(record: model))
+ }
+ }
+ }
+ override func navRightViewTapped() {
+ let tip = RecordTipsView(type: .tongchuan)
+ tip.show()
+ }
+
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+ navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = false
+
+ PcmSound.sharedInstance().delegate = sdk
+ CCAiManager.preparePlayBlueTooth()
+ }
+ override func viewDidDisappear(_ animated: Bool) {
+ super.viewDidDisappear(animated)
+ navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = true
+ CCAiManager.stopPlay()
+ }
+ override func navleftViewTapped() {
+ if toolBar.recordBtn.isSelected {
+ CustomAlert.showWith(title: "æç¤º".l10n, messgage: "å½åæ£å¨å½é³ï¼ç¡®å®æ¾å¼å½åå½é³åï¼".l10n, cancelCallback: {}) {
+ self.sdk.stop()
+ CCAiManager.stopPlay()
+ super.navleftViewTapped()
+ }
+ }
+ else{
+ super.navleftViewTapped()
+ }
+ }
+}
+
+extension DcTctyVC:RecordBarDelegate{
+ func recordBarLanguageChange(_ bar:RecordBar){
+ AiLanguageCache.save(type: .tscy_left, lan: bar.leftItem.language)
+ AiLanguageCache.save(type: .tscy_right, lan: bar.rightItem.language)
+ }
+ func recordBar(_ bar: RecordBar, stateChange state: RecordBarSate) {
+ if state == .start {
+ textView.text = nil
+ translateTextView.text = nil
+ sdk.start(from: toolBar.leftItem.language.value, to: toolBar.rightItem.language.value)
+ }
+ else if state == .stop{
+ sdk.stop()
+ bar.startAnimating()
+ }
+ }
+}
diff --git a/ShenYin/ShenYin/Sdk/DcSdk/VC/DcXclyVC.swift b/ShenYin/ShenYin/Sdk/DcSdk/VC/DcXclyVC.swift
new file mode 100644
index 0000000..ae9c8e1
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/DcSdk/VC/DcXclyVC.swift
@@ -0,0 +1,176 @@
+//
+// Untitled.swift
+// ShenYin
+//
+// Created by liangshi on 2025/12/26.
+//
+
+//
+// FieldRecordingVC.swift
+// ShenYin
+//
+// Created by liangshi on 2025/8/6.
+//
+
+import UIKit
+import AVFAudio
+class DcXclyVC:BaseVC{
+ let toolBar = FieldRecordBar()
+ let textView = UITextView()
+ let rhythView = RhythView()
+
+ var autoStart = false
+ var needSave = true
+ var bgEnter = false//æ¯å¦æ¯APPå¨åå°è¿å
¥è¿ä¸ªé¡µé¢ç
+
+ init(autoStart :Bool = false) {
+ self.autoStart = autoStart
+ super.init()
+ bgEnter = App.shared.isInBackground
+ setupSdk()
+ }
+
+ override func setupViews() {
+ navBar.title = "ç°åºå½é³".l10n
+ navBar.backgroundColor = .white
+ toolBar.do { v in
+ v.delegate = self
+ v.leftItem.language = AiLanguageCache.get(type: .xcly) ?? .chinse
+ }
+ view.backgroundColor = .white
+ textView.do { v in
+ v.isEditable = false
+ v.font = .regular(14)
+ v.text = ""
+ v.backgroundColor = .white
+ v.textColor = .hexString("#121212")
+ v.contentInset = UIEdgeInsets(top: 0, left: 18, bottom: 0, right: 18)
+ }
+ view.addSubviews([rhythView,textView,toolBar])
+ }
+ override func setupLayout() {
+ rhythView.snp.makeConstraints { make in
+ make.width.centerX.equalToSuperview()
+ make.top.equalToSuperview().inset(kNavBtm)
+ make.height.equalTo(110)
+ }
+ toolBar.snp.makeConstraints { make in
+ make.width.centerX.equalToSuperview()
+ make.height.equalTo(120)
+ make.bottom.equalToSuperview().inset(20)
+ }
+ textView.snp.makeConstraints { make in
+ make.top.equalTo(rhythView.snp.bottom)
+ make.left.right.equalToSuperview()
+ make.bottom.equalTo(toolBar.snp.top)
+ }
+ }
+
+ override func setupData() {
+ if bgEnter {
+ textView.text = DcXcly.shared.recordText
+ }
+ }
+
+ func setupSdk() {
+ DcXcly.shared.recordFinish = {[weak self] path in
+ guard let self = self else { return }
+ if !needSave {
+ return
+ }
+ let v = PopTextField()
+ v.show()
+ v.cancelTap = {
+ App.shared.popPage()
+ }
+ v.okTap = { [weak self] text in
+ guard let self = self else{return}
+ Logger.debug("111111 ===",textView.text ?? "")
+ let model = RecordDetailModel()
+ model.type = .present
+ model.from = toolBar.leftItem.language
+ model.to = .english
+ model.name = text
+ model.path = path
+ model.duration = YLToos.getDuration(model.path)
+ model.origin = textView.text
+ model.translate = ""
+ App.shared.popPage(animated: false)
+ App.shared.goToPage(RecordDetailVC(record: model))
+ }
+ }
+ DcXcly.shared.recordNeedReloadData = {[weak self] text in
+ guard let self = self else { return }
+ textView.text = text
+ textView.scrollToBottom()
+ }
+// DcXcly.shared.codeCallback = {[weak self] code in
+// guard let code = code else{return}
+// if code == 20001 {
+// self.recordBtn.isSelected = true
+// }
+// else if code == 20002 || code == 20003{
+// self.recordBtn.isSelected = false
+// }
+// }
+ if autoStart{
+ startRecord()
+ }
+ }
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+ navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = false
+ }
+ override func viewDidDisappear(_ animated: Bool) {
+ super.viewDidDisappear(animated)
+ navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = true
+ }
+ override func navleftViewTapped() {
+ if toolBar.recordBtn.isSelected {
+ CustomAlert.showWith(title: "æç¤º", messgage: "å½åæ£å¨å½é³ï¼ç¡®å®æ¾å¼å½åå½é³åï¼".l10n, cancelCallback: {}) {[unowned self] in
+ self.needSave = false
+ self.rhythView.stopTimer()
+ DcXcly.shared.recordStop()
+ self.navigationController?.popViewController(animated: true)
+ }
+ }
+ else{
+ super.navleftViewTapped()
+ }
+ }
+ func startRecord(){
+ toolBar.recordBtnAction()
+ rhythView.startTimer()
+ }
+ func stopRecord(){
+ toolBar.recordBtnAction()
+ rhythView.stopTimer()
+ }
+}
+
+extension DcXclyVC:FieldRecordBarDelegate{
+ func fieldRecordBar(_ bar: FieldRecordBar, languageChange language: CCAiLanguage) {
+ DcXcly.shared.setRecoordLanage(language)
+ AiLanguageCache.save(type: .xcly, lan: language)
+ }
+
+ func fieldRecordBar(_ bar: FieldRecordBar, stateChange state: RecordSate) {
+ if state == .start {
+ DcXcly.shared.recordStart()
+ rhythView.startTimer()
+ }
+ if state == .resume{
+ rhythView.startTimer()
+ DcXcly.shared.recordResume()
+ }
+ else if state == .pause{
+ DcXcly.shared.recordPause()
+ rhythView.stopTimer()
+ }
+ else if state == .stop{
+ rhythView.stopTimer()
+ DcXcly.shared.recordStop()
+ bar.startAnimating()
+ }
+ }
+}
diff --git a/ShenYin/ShenYin/Sdk/JoySdk/JoyChat.swift b/ShenYin/ShenYin/Sdk/JoySdk/JoyChat.swift
index 2dbac9c..08479bd 100644
--- a/ShenYin/ShenYin/Sdk/JoySdk/JoyChat.swift
+++ b/ShenYin/ShenYin/Sdk/JoySdk/JoyChat.swift
@@ -34,7 +34,7 @@ extension JoyChat : JoyGemChatManagerDelegate {
isTtsPlaying = true
Logger.debug("å¼å§ææ¾")
JoyGemChatManager.shared().playAudioStart()
- App.shared.preparePlay()
+ CCAiManager.preparePlayBlueTooth()
}
Logger.debug("æ¶å°é³é¢æ°æ®", data?.count ?? 0)
PcmSound.sharedInstance().feed(data)
@@ -47,7 +47,7 @@ extension JoyChat : JoyGemChatManagerDelegate {
case .startRecord:
if (isTtsPlaying) {
isTtsPlaying = false
- App.shared.preparePlay()
+ CCAiManager.preparePlayBlueTooth()
}
break
case .stopRecord:
diff --git a/ShenYin/ShenYin/Sdk/JoySdk/JoyChinse2English.swift b/ShenYin/ShenYin/Sdk/JoySdk/JoyChinse2English.swift
new file mode 100644
index 0000000..f8a93f1
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/JoySdk/JoyChinse2English.swift
@@ -0,0 +1,104 @@
+//
+// JoyChinse2English.swift
+// ShenYin
+//
+// Created by liangshi on 2025/12/26.
+//
+import JoyGemAI
+
+class JoyChinse2English:NSObject{
+ var dataList:[(Chinese2EnglishCellModel,Int)] = []
+ var startIndex = 0//è®°å½å¼å§å½é³ç次æ°ï¼ç¨äºåºåè¿åçæ°æ®
+
+ var stopCallback:(()->Void)?
+ var refreshDataCallback:(()->Void)?
+ override init(){
+ super.init()
+ JoyGemSIManager.shared().delegate = self
+ PcmSound.sharedInstance().delegate = self
+ }
+
+ func start(){
+ startIndex += 100000
+ // JoyGemSIManager.shared().originalLanguage = bar.leftItem.language.value
+ // JoyGemSIManager.shared().targetLanguage = bar.rightItem.language.value
+ JoyGemSIManager.shared().start()
+ // do {
+ // try AVAudioSession.sharedInstance().setCategory(.playAndRecord, options: [.defaultToSpeaker])
+ // try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
+ // } catch {
+ // print(error)
+ // }
+ }
+
+ func stop(){
+ JoyGemSIManager.shared().stop()
+ }
+
+}
+extension JoyChinse2English : JoyGemSIManagerDelegate {
+ func siManagerStopped(_ manager: JoyGemSIManager, reason code: JoyGemRecordStopCode) {
+ stopCallback?()
+ Logger.debug("忢",code.rawValue)
+// if code == .passively {
+// toolBar.recordBtn.isSelected = false
+// }
+ }
+
+ func siManager(_ manager: JoyGemSIManager, didUpdateRaw model: JoyGemAsrModel) {
+ Logger.debug("text: \(model.text),index: \(model.index)")
+ let msg = dataList.firstIndex (where: { (str,idx) in
+ return idx == Int(model.index) + startIndex
+ })
+ if (msg == nil) {
+ dataList.append((Chinese2EnglishCellModel(send: model.text),Int(model.index) + startIndex))
+ } else {
+ let (item,_) = dataList[msg!]
+ item.send = model.text
+ }
+ //
+ // ///çå¬å°ä¸å¥è¯ç»æï¼èªå¨ç»æå½åå½é³
+ // if (model.definite == true) {
+ // stopEarRecord()
+ // }
+ refreshDataCallback?()
+ }
+
+ func siManager(_ manager: JoyGemSIManager, didUpdateTranslate model: JoyGemAsrModel) {
+ let msg = dataList.firstIndex (where: { (str,idx) in
+ return idx == Int(model.index) + startIndex
+ })
+ if (msg == nil) {
+ dataList.append((Chinese2EnglishCellModel(response: model.text),Int(model.index) + startIndex))
+ } else {
+ let (item,_) = dataList[msg!]
+ item.response = model.text
+ }
+ refreshDataCallback?()
+ }
+
+ func siManager(_ manager: JoyGemSIManager, saveFile path: String) {
+ Logger.debug("path: \(path)")
+ }
+
+
+ func siManager(_ manager: JoyGemSIManager, stateChange code: JoyGemStateCode) {
+ Logger.debug("code: \(code)")
+ }
+
+ func siManagerStopped(_ manager: JoyGemSIManager) {
+
+ }
+ func siManager(_ manager: JoyGemSIManager, didUpdateAudioData data: Data, sampleRate: UInt) {
+ PcmSound.sharedInstance().feed(data)
+ }
+
+ func siManager(_ manager: JoyGemSIManager, onError code: JoyGemErrorCode) {
+
+ }
+}
+extension JoyChinse2English:PcmSoundDelegate{
+ func remaining(_ frames: UInt) {
+
+ }
+}
diff --git a/ShenYin/ShenYin/Sdk/JoySdk/JoyDialog.swift b/ShenYin/ShenYin/Sdk/JoySdk/JoyDialog.swift
new file mode 100644
index 0000000..c640165
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/JoySdk/JoyDialog.swift
@@ -0,0 +1,16 @@
+//
+// JoyDialog.swift
+// ShenYin
+//
+// Created by liangshi on 2025/12/29.
+//
+
+class JoyDialog: NSObject {
+
+
+
+
+
+
+
+}
diff --git a/ShenYin/ShenYin/Sdk/JoySdk/JoySdkManager.swift b/ShenYin/ShenYin/Sdk/JoySdk/JoySdkManager.swift
index 4149aa3..4e9a702 100644
--- a/ShenYin/ShenYin/Sdk/JoySdk/JoySdkManager.swift
+++ b/ShenYin/ShenYin/Sdk/JoySdk/JoySdkManager.swift
@@ -116,7 +116,7 @@ extension JoySdkManager : JoyGemAIManagerDelegate {
}
func joyGemAuthSuccessCallback() {
Logger.debug("é´ææå")
- App.shared.preparePlay()
+ CCAiManager.preparePlayBlueTooth()
DeviceCache.saveLastConnected(mac: CCBleManager.shared.connectPeripheral!.mac)
DeviceCache.shared.add(CCBleManager.shared.connectPeripheral!.device.identifier.uuidString, mac: CCBleManager.shared.connectPeripheral!.mac)
@@ -134,40 +134,40 @@ extension JoySdkManager : JoyGemAIManagerDelegate {
switch action {
case .cancel:
Logger.debug("请æ±å
³éå½é³åè½/éç¥å
³éäºå¯¹è¯")
- if let topVC = App.shared.topVC(), let vc = topVC as? FieldRecordingVC {
+ if let topVC = App.shared.topVC(), let vc = topVC as? JoyXclyVC {
vc.stopRecord()
}
- if let topVC = App.shared.topVC(), let vc = topVC as? CallingRecordVC {
+ if let topVC = App.shared.topVC(), let vc = topVC as? JoyCallingRecordVC {
vc.stopRecord()
}
- if let topVC = App.shared.topVC(), let vc = topVC as? StereoCallVC {
+ if let topVC = App.shared.topVC(), let vc = topVC as? JoyStereoCallVC {
vc.stopRecord()
}
JoySdkManager.shared.record.recordStop()
case .recordLive:
Logger.debug("请æ±å¼å¯ç°åºå½é³")
- if let vc = App.shared.topVC() as? FieldRecordingVC {
+ if let vc = App.shared.topVC() as? JoyXclyVC {
vc.startRecord()
}
else{
- App.shared.goToPage(FieldRecordingVC(autoStart: true))
+ App.shared.goToPage(JoyXclyVC(autoStart: true))
JoySdkManager.shared.record.recordStart()
}
case .recordCall:
Logger.debug("请æ±å¼å¯éè¯å½é³")
if JoySdkManager.shared.callRecord.supportStereo{
- if let vc = App.shared.topVC() as? StereoCallVC {
+ if let vc = App.shared.topVC() as? JoyStereoCallVC {
vc.startRecord()
}else{
- App.shared.goToPage(CallingRecordVC(autoStart: true))
+ App.shared.goToPage(JoyCallingRecordVC(autoStart: true))
JoySdkManager.shared.callRecord.callRecordStart()
}
}
else{
- if let vc = App.shared.topVC() as? CallingRecordVC {
+ if let vc = App.shared.topVC() as? JoyCallingRecordVC {
vc.startRecord()
}else{
- App.shared.goToPage(CallingRecordVC(autoStart: true))
+ App.shared.goToPage(JoyCallingRecordVC(autoStart: true))
JoySdkManager.shared.callRecord.callRecordStart()
}
}
@@ -176,8 +176,8 @@ extension JoySdkManager : JoyGemAIManagerDelegate {
Logger.debug( "请æ±å¼å¯åä¼ å¬è¯")
case .chat:
Logger.debug("éç¥å¼å¯AI对è¯")
- if !App.shared.topVC().isKind(of: ChatVC.self) {
- App.shared.goToPage(ChatVC())
+ if !App.shared.topVC().isKind(of: JoyChatVC.self) {
+ App.shared.goToPage(JoyChatVC())
}
@unknown default:
break
diff --git a/ShenYin/ShenYin/Sdk/JoySdk/JoyTcty.swift b/ShenYin/ShenYin/Sdk/JoySdk/JoyTcty.swift
new file mode 100644
index 0000000..368ae4c
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/JoySdk/JoyTcty.swift
@@ -0,0 +1,120 @@
+//
+// JoyTcty.swift
+// ShenYin
+//
+// Created by liangshi on 2025/12/29.
+//
+
+import JoyGemAI
+
+class JoyTcty:NSObject{
+ var messageList : [(String,UInt)] = []
+ var translateList : [(String,UInt)] = []
+ var recordFilePath : String?
+
+
+ var stopCallback:(()->Void)?
+ var refreshOriginCallback:((String)->Void)?
+ var refreshTranslateCallback:((String)->Void)?
+ var filePathCallback:((String)->Void)?
+
+ override init(){
+ super.init()
+ JoyGemSIManager.shared().delegate = self
+ PcmSound.sharedInstance().delegate = self
+ }
+
+ func start(from:String,to:String){
+ messageList.removeAll()
+ translateList.removeAll()
+
+ if Thread.isMainThread {
+ do {
+ try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [])
+ try AVAudioSession.sharedInstance().setActive(true)
+ } catch let error as NSError {
+ Logger.debug("An error occurred setting the audio session category: \(error.localizedDescription)")
+ }
+ } else {
+ DispatchQueue.main.sync {
+ do {
+ try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [])
+ try AVAudioSession.sharedInstance().setActive(true)
+ } catch let error as NSError {
+ Logger.debug("An error occurred setting the audio session category: \(error.localizedDescription)")
+ }
+ }
+ }
+ JoyGemSIManager.shared().originalLanguage = from
+ JoyGemSIManager.shared().targetLanguage = to
+ JoyGemSIManager.shared().start()
+ }
+
+ func stop(){
+ JoyGemSIManager.shared().stop()
+ }
+
+}
+
+extension JoyTcty : JoyGemSIManagerDelegate {
+ func siManagerStopped(_ manager: JoyGemSIManager, reason code: JoyGemRecordStopCode) {
+ stopCallback?()
+ }
+
+ func siManager(_ manager: JoyGemSIManager, didUpdateRaw model: JoyGemAsrModel) {
+ let msg = messageList.firstIndex (where: { (str,idx) in
+ return idx == model.index;
+ })
+ if (msg == nil) {
+ messageList.append((model.text,model.index))
+ } else {
+ messageList[msg!] = (model.text,model.index)
+ }
+
+ let text = messageList.compactMap({ (str,idx) in
+ return str
+ }).joined(separator: "\n")
+ refreshOriginCallback?(text)
+ }
+
+ func siManager(_ manager: JoyGemSIManager, didUpdateTranslate model: JoyGemAsrModel) {
+ Logger.debug("translate text: \(model.text),index: \(model.index)")
+ let msg = translateList.firstIndex (where: { (str,idx) in
+ return idx == model.index;
+ })
+ if (msg == nil) {
+ translateList.append((model.text,model.index))
+ } else {
+ translateList[msg!] = (model.text,model.index)
+ }
+
+ let text = translateList.compactMap({ (str,idx) in
+ return str
+ }).joined(separator: "\n")
+ refreshTranslateCallback?(text)
+ }
+
+
+ func siManager(_ manager: JoyGemSIManager, saveFile path: String) {
+ Logger.debug("path: \(path)")
+ recordFilePath = path
+ filePathCallback?(path)
+ }
+
+ func siManager(_ manager: JoyGemSIManager, stateChange code: JoyGemStateCode) {
+ Logger.debug("code: \(code)")
+ }
+
+ func siManager(_ manager: JoyGemSIManager, didUpdateAudioData data: Data, sampleRate: UInt) {
+ PcmSound.sharedInstance().feed(data)
+ }
+ func siManager(_ manager: JoyGemSIManager, onError code: JoyGemErrorCode) {
+
+ }
+}
+
+extension JoyTcty : PcmSoundDelegate {
+ func remaining(_ frames: UInt) {
+ Logger.debug("[frame:\(frames)]");
+ }
+}
diff --git a/ShenYin/ShenYin/UI/Home/CallingRecordVC.swift b/ShenYin/ShenYin/Sdk/JoySdk/VC/JoyCallingRecordVC.swift
similarity index 98%
rename from ShenYin/ShenYin/UI/Home/CallingRecordVC.swift
rename to ShenYin/ShenYin/Sdk/JoySdk/VC/JoyCallingRecordVC.swift
index 9f92411..0ede8b8 100644
--- a/ShenYin/ShenYin/UI/Home/CallingRecordVC.swift
+++ b/ShenYin/ShenYin/Sdk/JoySdk/VC/JoyCallingRecordVC.swift
@@ -1,5 +1,5 @@
//
-// CallingRecordVC.swift
+// JoyCallingRecordVC.swift
// ShenYin
//
// Created by liangshi on 2025/8/6.
@@ -7,7 +7,7 @@
import UIKit
import AVFAudio
-class CallingRecordVC:BaseVC{
+class JoyCallingRecordVC:BaseVC{
let toolBar = FieldRecordBar()
let textView = UITextView()
let rhythView = RhythView()
@@ -151,7 +151,7 @@ class CallingRecordVC:BaseVC{
}
}
-extension CallingRecordVC:FieldRecordBarDelegate{
+extension JoyCallingRecordVC:FieldRecordBarDelegate{
func fieldRecordBar(_ bar: FieldRecordBar, languageChange language: CCAiLanguage) {
JoySdkManager.shared.callRecord.setCallRecoordLanage(language)
AiLanguageCache.save(type: .thly, lan: language)
diff --git a/ShenYin/ShenYin/UI/Home/Chat/ChatVC.swift b/ShenYin/ShenYin/Sdk/JoySdk/VC/JoyChatVC.swift
similarity index 88%
rename from ShenYin/ShenYin/UI/Home/Chat/ChatVC.swift
rename to ShenYin/ShenYin/Sdk/JoySdk/VC/JoyChatVC.swift
index 0b63f91..ee53a3f 100644
--- a/ShenYin/ShenYin/UI/Home/Chat/ChatVC.swift
+++ b/ShenYin/ShenYin/Sdk/JoySdk/VC/JoyChatVC.swift
@@ -8,7 +8,7 @@
import UIKit
import JoyGemAI
import AVFAudio
-class ChatVC:BaseVC{
+class JoyChatVC:BaseVC{
let rightItem = ChatNavigationBarItem(frame: CGRect(x: 0, y: 0, width: 80, height: 44))
let roleItem = ChatRoleItem(frame: CGRect(x: 0, y: 0, width: 100, height: 44))
@@ -17,11 +17,10 @@ class ChatVC:BaseVC{
let headerView = ChatHeaderView(frame: CGRect(x: 0, y: 0, width: kScreenWid, height: 260))
let tipsLabel = UILabel()
- var roleList:[JoyGemSpeaker] = []
+ var roleList:[CCRole] = []
deinit {
- PcmSound.sharedInstance().stopAudioUnit()
- PcmSound.sharedInstance().cleanup()
+ CCAiManager.stopPlay()
JoyGemChatManager.shared().removeObserver(self, forKeyPath: "isActive")
}
@@ -142,7 +141,12 @@ class ChatVC:BaseVC{
guard let self = self else{return}
roleItem.role = model
headerView.update(name: model.name, role: model.role)
- JoyGemChatManager.shared().setSpeaker(model)
+ let joyMode = JoyGemSpeaker()
+ joyMode.role = model.role
+ joyMode.sid = model.sid
+ joyMode.name = model.name
+ joyMode.type = model.type
+ JoyGemChatManager.shared().setSpeaker(joyMode)
}
App.shared.goToPage(vc)
}
@@ -155,8 +159,8 @@ class ChatVC:BaseVC{
func loadRoleList(){
JoyGemChatManager.shared().getSpeakerList {[weak self] speakers in
guard let self = self,speakers.count > 0 else{return}
- self.roleList = speakers
- self.roleList.insert(xiaoYinRole(), at: 0)
+ self.roleList = speakers.map{CCRole(sid: $0.sid, name: $0.name, type: $0.type, role: $0.role)}
+ self.roleList.insert(CCRole.xiaoYin, at: 0)
var currentRole = roleList.first
if let cacheRole = RoleCache.get(){
@@ -169,20 +173,17 @@ class ChatVC:BaseVC{
}
self.roleItem.role = currentRole
self.headerView.update(name: self.roleItem.role.name, role: self.roleItem.role.role)
- JoyGemChatManager.shared().setSpeaker(self.roleItem.role)
+ let joyMode = JoyGemSpeaker()
+ joyMode.role = self.roleItem.role.role
+ joyMode.sid = self.roleItem.role.sid
+ joyMode.name = self.roleItem.role.name
+ joyMode.type = self.roleItem.role.type
+ JoyGemChatManager.shared().setSpeaker(joyMode)
}
}
- func xiaoYinRole()->JoyGemSpeaker{
- let model = JoyGemSpeaker()
- model.sid = "zh_female_tianmeitaozi_mars_bigtts"
- model.name = "å°é³"
- model.type = "default"
- model.role = "test_xiaoyin"
- return model
- }
}
-extension ChatVC:ChatRecordBarDelegate{
+extension JoyChatVC:ChatRecordBarDelegate{
func recordBarCancel(_ toolBar: ChatRecordBar) {
// JoyGemChatManager.shared().stopChat()
JoyGemChatManager.shared().stopSingleChat()
@@ -209,7 +210,7 @@ extension ChatVC:ChatRecordBarDelegate{
}
}
-extension ChatVC:UITableViewDelegate,UITableViewDataSource {
+extension JoyChatVC:UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return JoySdkManager.shared.chat.dataList.count
}
diff --git a/ShenYin/ShenYin/UI/Home/Chinese2English/Chinese2EnglishVC.swift b/ShenYin/ShenYin/Sdk/JoySdk/VC/JoyChinese2EnglishVC.swift
similarity index 51%
rename from ShenYin/ShenYin/UI/Home/Chinese2English/Chinese2EnglishVC.swift
rename to ShenYin/ShenYin/Sdk/JoySdk/VC/JoyChinese2EnglishVC.swift
index 4363db3..0fcfc68 100644
--- a/ShenYin/ShenYin/UI/Home/Chinese2English/Chinese2EnglishVC.swift
+++ b/ShenYin/ShenYin/Sdk/JoySdk/VC/JoyChinese2EnglishVC.swift
@@ -6,15 +6,13 @@
//
import UIKit
-import JoyGemAI
import AVFAudio
-class Chinese2EnglishVC:BaseVC{
+class JoyChinese2EnglishVC:BaseVC{
let toolBar = RecordBar()
let tableView = UITableView(frame: CGRectZero, style: .plain)
let bg = UIImageView()
+ let sdk = JoyChinse2English()
var dataList:[(Chinese2EnglishCellModel,Int)] = []
- var recordFilePath : String?
- var startIndex = 0//è®°å½å¼å§å½é³ç次æ°ï¼ç¨äºåºåè¿åçæ°æ®
// deinit {
// PcmSound.sharedInstance().stopAudioUnit()
@@ -60,32 +58,40 @@ class Chinese2EnglishVC:BaseVC{
}
}
override func setupData() {
- JoyGemSIManager.shared().delegate = self
-
if TipsCache.needShow(type: .chinese2english) {
RecordTipsView(type: .chinese2english).show()
}
+ sdk.stopCallback = {[weak self] in
+ guard let self = self else{return}
+ toolBar.recordBtn.isSelected = false
+ }
+ sdk.refreshDataCallback = {[weak self] in
+ guard let self = self else{return}
+ dataList = sdk.dataList
+ refreshData()
+ }
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = false
- PcmSound.sharedInstance().delegate = self;
- App.shared.preparePlay()
+ PcmSound.sharedInstance().delegate = sdk
+ CCAiManager.preparePlayBlueTooth()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = true
- App.shared.preparePlay()
+ CCAiManager.preparePlayBlueTooth()
}
override func navleftViewTapped() {
if toolBar.recordBtn.isSelected {
- CustomAlert.showWith(title: "æç¤º".l10n, messgage: "å½åæ£å¨å½é³ï¼ç¡®å®æ¾å¼å½åå½é³å".l10n, cancelCallback: {}) {
-// JoyGemSIManager.shared().stop()
-// PcmSound.sharedInstance().stopAudioUnit()
-// PcmSound.sharedInstance().cleanup()
- super.navleftViewTapped()
- }
+ self.sdk.stop()
+// CustomAlert.showWith(title: "æç¤º".l10n, messgage: "å½åæ£å¨å½é³ï¼ç¡®å®æ¾å¼å½åå½é³å".l10n, cancelCallback: {}) {
+// self.sdk.stop()
+//// PcmSound.sharedInstance().stopAudioUnit()
+//// PcmSound.sharedInstance().cleanup()
+// super.navleftViewTapped()
+// }
}
else{
super.navleftViewTapped()
@@ -106,36 +112,27 @@ class Chinese2EnglishVC:BaseVC{
}
}
}
-extension Chinese2EnglishVC:RecordBarDelegate{
+extension JoyChinese2EnglishVC:RecordBarDelegate{
func recordBarLanguageChange(_ bar: RecordBar) {
}
func recordBar(_ bar: RecordBar, stateChange state: RecordBarSate) {
if state == .start {
- startIndex += 100000
-// JoyGemSIManager.shared().originalLanguage = bar.leftItem.language.value
-// JoyGemSIManager.shared().targetLanguage = bar.rightItem.language.value
- JoyGemSIManager.shared().start()
-// do {
-// try AVAudioSession.sharedInstance().setCategory(.playAndRecord, options: [.defaultToSpeaker])
-// try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
-// } catch {
-// print(error)
-// }
+ sdk.start()
}
else if state == .stop{
- JoyGemSIManager.shared().stop()
+ sdk.stop()
}
}
}
-extension Chinese2EnglishVC:UITableViewDelegate,UITableViewDataSource {
+extension JoyChinese2EnglishVC:UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = Chinese2EnglishCell.cell(withTableView: tableView, indexPath: indexPath)
- let (vallue,index) = dataList[indexPath.row]
+ let (vallue,_) = dataList[indexPath.row]
cell.data = vallue
return cell
}
@@ -143,70 +140,3 @@ extension Chinese2EnglishVC:UITableViewDelegate,UITableViewDataSource {
}
}
-
-extension Chinese2EnglishVC : JoyGemSIManagerDelegate {
- func siManagerStopped(_ manager: JoyGemSIManager, reason code: JoyGemRecordStopCode) {
- Logger.debug("忢",code.rawValue)
- if code == .passively {
- toolBar.recordBtn.isSelected = false
- }
- }
-
- func siManager(_ manager: JoyGemSIManager, didUpdateRaw model: JoyGemAsrModel) {
- Logger.debug("text: \(model.text),index: \(model.index)")
- let msg = dataList.firstIndex (where: { (str,idx) in
- return idx == Int(model.index) + startIndex
- })
- if (msg == nil) {
- dataList.append((Chinese2EnglishCellModel(send: model.text),Int(model.index) + startIndex))
- } else {
- let (item,_) = dataList[msg!]
- item.send = model.text
- }
- //
- // ///çå¬å°ä¸å¥è¯ç»æï¼èªå¨ç»æå½åå½é³
- // if (model.definite == true) {
- // stopEarRecord()
- // }
- refreshData()
- }
-
- func siManager(_ manager: JoyGemSIManager, didUpdateTranslate model: JoyGemAsrModel) {
- let msg = dataList.firstIndex (where: { (str,idx) in
- return idx == Int(model.index) + startIndex
- })
- if (msg == nil) {
- dataList.append((Chinese2EnglishCellModel(response: model.text),Int(model.index) + startIndex))
- } else {
- let (item,_) = dataList[msg!]
- item.response = model.text
- }
- refreshData()
- }
-
- func siManager(_ manager: JoyGemSIManager, saveFile path: String) {
- Logger.debug("path: \(path)")
- recordFilePath = path
- }
-
-
- func siManager(_ manager: JoyGemSIManager, stateChange code: JoyGemStateCode) {
- Logger.debug("code: \(code)")
- }
-
- func siManagerStopped(_ manager: JoyGemSIManager) {
-
- }
- func siManager(_ manager: JoyGemSIManager, didUpdateAudioData data: Data, sampleRate: UInt) {
- PcmSound.sharedInstance().feed(data)
- }
-
- func siManager(_ manager: JoyGemSIManager, onError code: JoyGemErrorCode) {
-
- }
-}
-extension Chinese2EnglishVC:PcmSoundDelegate{
- func remaining(_ frames: UInt) {
-
- }
-}
diff --git a/ShenYin/ShenYin/Sdk/JoySdk/VC/JoyDialogTranlateVC.swift b/ShenYin/ShenYin/Sdk/JoySdk/VC/JoyDialogTranlateVC.swift
new file mode 100644
index 0000000..c81a8b2
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/JoySdk/VC/JoyDialogTranlateVC.swift
@@ -0,0 +1,357 @@
+//
+// JoyDialogTranslateVC.swift
+// ShenYin
+//
+// Created by liangshi on 2025/8/6.
+//
+
+import UIKit
+import JoyGemAI
+import AVFoundation
+class JoyDialogTranslateVC:BaseVC{
+ let toolBar = DialogRecordBar()
+
+ let splitView = DialogSplitView()
+ let tableView = UITableView(frame: CGRectZero, style: .plain)
+ var dataList:[DialogTranslateCellModel] = []
+
+ var tmpList : [(String,UInt)] = []
+ var tmpOtherList : [(String,UInt)] = []
+ deinit {
+ CCAiManager.stopPlay()
+ }
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ }
+ override func setupViews() {
+ view.addSubviews([toolBar,tableView,splitView])
+
+ navBar.title = "对è¯ç¿»è¯".l10n
+ navBar.rightView.isHidden = false
+ navBar.rightView.setImage(UIImage(named: "help_icon"), for: .normal)
+
+ toolBar.do { v in
+// v.backgroundColor = .clear
+ v.delegate = self
+ v.navBar = navBar
+ }
+ view.backgroundColor = .hexString("#F7F7F7")
+
+ tableView.do { v in
+ v.backgroundColor = .hexString("#F7F7F7")
+ v.delegate = self
+ v.dataSource = self
+ v.estimatedRowHeight = 60
+ v.separatorStyle = .none
+ v.register(DialogTranslateCell.self, forCellReuseIdentifier: DialogTranslateCell.reuseID)
+ }
+ splitView.isHidden = true
+
+ }
+ override func setupLayout() {
+ toolBar.snp.makeConstraints { make in
+ make.width.centerX.equalToSuperview()
+ make.height.equalTo(120)
+ make.bottom.equalToSuperview()
+ }
+ tableView.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(kNavBtm)
+ make.left.equalToSuperview()
+ make.width.equalTo(kScreenWid)
+ make.bottom.equalTo(toolBar.snp.top)
+ }
+ splitView.snp.makeConstraints { make in
+ make.edges.equalTo(tableView)
+ }
+ }
+ override func setupData() {
+ JoyGemSIManager.shared().delegate = self
+ JoyGemSIDeviceManager.shared().delegate = self
+
+ PcmSound.sharedInstance().delegate = self;
+ PcmSound.sharedInstance().setup(16000, withchannels: 1)
+ do {
+ try AVAudioSession.sharedInstance().setActive(true)
+ } catch {
+ print(error)
+ }
+
+ if TipsCache.needShow(type: .dialog) {
+ RecordTipsView(type: .dialog).show()
+ }
+ }
+ override func navRightViewTapped() {
+ let tip = RecordTipsView(type: .dialog)
+ tip.show()
+ }
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+ navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = false
+ }
+ override func viewDidDisappear(_ animated: Bool) {
+ super.viewDidDisappear(animated)
+ navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = true
+ }
+ override func navleftViewTapped() {
+ JoyGemSIManager.shared().stop()
+ JoyGemSIDeviceManager.shared().stop()
+ CCAiManager.stopPlay()
+ super.navleftViewTapped()
+ }
+
+ func refreshData(){
+ tableView.reloadData()
+ if dataList.count > 0 {
+ tableView.scrollToRow(at: IndexPath(row: dataList.count - 1, section: 0), at: .none, animated: true)
+ }
+ splitView.dataList = dataList
+ }
+}
+
+extension JoyDialogTranslateVC:UITableViewDelegate,UITableViewDataSource {
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return dataList.count
+ }
+
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let cell = DialogTranslateCell.cell(withTableView: tableView, indexPath: indexPath)
+ cell.data = dataList[indexPath.row]
+ return cell
+ }
+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+
+ }
+}
+
+extension JoyDialogTranslateVC:DialogRecordBarDelegate{
+ func recordBar(_ bar: DialogRecordBar, layoutChange: DialogRecordLayoutType) {
+ if layoutChange == .spolit{
+ splitView.isHidden = false
+ splitView.dataList = dataList
+ }
+ else{
+ splitView.isHidden = true
+ }
+ }
+
+ func recordBar(_ bar: DialogRecordBar, device: DialogRecordDeviceType, stateChange state: RecordBarSate) {
+ if device == .earphone {
+ if state == .start {
+ startEarRecord()
+ }
+ else{
+ stopEarRecord()
+ }
+ }
+ else if device == .phone{
+ if state == .start {
+ startPhoneRecord()
+ }
+
+ else{
+ stopPhoneRecord()
+ }
+ }
+ }
+ @objc func startPhoneRecord() {
+ tmpList.removeAll()
+ tmpOtherList.removeAll()
+ let model = DialogTranslateCellModel()
+ model.isPhone = true
+ dataList.append(model)
+ refreshData()
+
+ JoyGemSIManager.shared().originalLanguage = toolBar.languageView.rightItem.language.value
+ JoyGemSIManager.shared().targetLanguage = toolBar.languageView.leftItem.language.value
+ Logger.debug("æºè¯è¨",JoyGemSIManager.shared().originalLanguage)
+ Logger.debug("ç®æ è¯è¨",JoyGemSIManager.shared().targetLanguage)
+ JoyGemSIManager.shared().start()
+ }
+
+ @objc func stopPhoneRecord() {
+ JoyGemSIManager.shared().stop()
+ }
+
+ @objc func startEarRecord() {
+ tmpList.removeAll()
+ tmpOtherList.removeAll()
+ let model = DialogTranslateCellModel()
+ model.isPhone = false
+ dataList.append(model)
+ refreshData()
+
+ JoyGemSIDeviceManager.shared().originalLanguage = toolBar.languageView.leftItem.language.value
+ JoyGemSIDeviceManager.shared().targetLanguage = toolBar.languageView.rightItem.language.value
+ JoyGemSIDeviceManager.shared().start()
+ do {
+ try AVAudioSession.sharedInstance().setCategory(.playAndRecord, options: [.defaultToSpeaker])
+ try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
+ } catch {
+ print(error)
+ }
+ }
+
+ @objc func stopEarRecord() {
+ JoyGemSIDeviceManager.shared().stop()
+ }
+}
+
+extension JoyDialogTranslateVC : JoyGemSIManagerDelegate {
+
+
+ func siManagerStopped(_ manager: JoyGemSIManager, reason code: JoyGemRecordStopCode) {
+ if let model = dataList.last,model.send.isEmpty{
+ dataList.removeLast()
+ refreshData()
+ }
+ }
+
+ func siManager(_ manager: JoyGemSIManager, didUpdateRaw model: JoyGemAsrModel) {
+ let msg = tmpList.firstIndex (where: { (str,idx) in
+ return idx == model.index;
+ })
+ if (msg == nil) {
+ tmpList.append((model.text,model.index))
+ } else {
+ tmpList[msg!] = (model.text,model.index)
+ }
+
+ ///çå¬å°ä¸å¥è¯ç»æï¼èªå¨ç»æå½åå½é³
+ if (model.definite == true) {
+ toolBar.stopRecord(.phone)
+ stopPhoneRecord()
+ }
+
+ guard let model = dataList.last else {
+ return
+ }
+
+ model.send = tmpList.compactMap({ (str,idx) in
+ return str
+ }).joined(separator: "\n")
+ refreshData()
+ }
+
+ func siManager(_ manager: JoyGemSIManager, didUpdateTranslate model: JoyGemAsrModel) {
+ let msg = tmpOtherList.firstIndex (where: { (str,idx) in
+ return idx == model.index;
+ })
+ if (msg == nil) {
+ tmpOtherList.append((model.text,model.index))
+ } else {
+ tmpOtherList[msg!] = (model.text,model.index)
+ }
+
+ guard let model = dataList.last else {
+ return
+ }
+
+ model.response = tmpOtherList.compactMap({ (str,idx) in
+ return str
+ }).joined(separator: "\n")
+ refreshData()
+ }
+
+ func siManager(_ manager: JoyGemSIManager, saveFile path: String) {
+
+ }
+
+
+ func siManager(_ manager: JoyGemSIManager, stateChange code: JoyGemStateCode) {
+
+ }
+
+ func siManagerStopped(_ manager: JoyGemSIManager) {
+
+ }
+ func siManager(_ manager: JoyGemSIManager, didUpdateAudioData data: Data, sampleRate: UInt) {
+ PcmSound.sharedInstance().feed(data)
+ }
+ func siManager(_ manager: JoyGemSIManager, onError code: JoyGemErrorCode) {
+
+ }
+}
+
+extension JoyDialogTranslateVC : JoyGemSIDeviceManagerDelegate {
+
+
+
+ func siDeviceManagerStopped(_ manager: JoyGemSIDeviceManager, reason code: JoyGemRecordStopCode) {
+ if let model = dataList.last,model.send.isEmpty{
+ dataList.removeLast()
+ refreshData()
+ }
+ }
+
+ func siDeviceManager(_ manager: JoyGemSIDeviceManager, didUpdateRaw model: JoyGemAsrModel) {
+ Logger.debug("text: \(model.text),index: \(model.index)")
+ let msg = tmpList.firstIndex (where: { (str,idx) in
+ return idx == model.index;
+ })
+ if (msg == nil) {
+ tmpList.append((model.text,model.index))
+ } else {
+ tmpList[msg!] = (model.text,model.index)
+ }
+
+ ///çå¬å°ä¸å¥è¯ç»æï¼èªå¨ç»æå½åå½é³
+ if (model.definite == true) {
+ toolBar.stopRecord(.earphone)
+ stopEarRecord()
+ }
+
+ guard let model = dataList.last else {
+ return
+ }
+
+ model.send = tmpList.compactMap({ (str,idx) in
+ return str
+ }).joined(separator: "\n")
+ refreshData()
+ }
+
+ func siDeviceManager(_ manager: JoyGemSIDeviceManager, didUpdateTranslate model: JoyGemAsrModel) {
+ let msg = tmpOtherList.firstIndex (where: { (str,idx) in
+ return idx == model.index;
+ })
+ if (msg == nil) {
+ tmpOtherList.append((model.text,model.index))
+ } else {
+ tmpOtherList[msg!] = (model.text,model.index)
+ }
+
+ guard let model = dataList.last else {
+ return
+ }
+
+ model.response = tmpOtherList.compactMap({ (str,idx) in
+ return str
+ }).joined(separator: "\n")
+ refreshData()
+ }
+ func siDeviceManager(_ manager: JoyGemSIDeviceManager, didUpdateAudioData data: Data, sampleRate: UInt) {
+ PcmSound.sharedInstance().feed(data)
+ }
+ func siDeviceManager(_ manager: JoyGemSIDeviceManager, update mode: JoyGemRecordMode) {
+
+ }
+
+ func siDeviceManager(_ manager: JoyGemSIDeviceManager, saveFile path: String) {
+ Logger.debug("path: \(path)")
+ }
+
+ func siDeviceManager(_ manager: JoyGemSIDeviceManager, stateChange code: JoyGemStateCode) {
+ Logger.debug("code: \(code)")
+ }
+
+ func siDeviceManager(_ manager: JoyGemSIDeviceManager, onError code: JoyGemErrorCode) {
+
+ }
+}
+
+
+extension JoyDialogTranslateVC : PcmSoundDelegate {
+ func remaining(_ frames: UInt) {
+ Logger.debug("[frame:\(frames)]");
+ }
+}
diff --git a/ShenYin/ShenYin/UI/Home/StereoCallVC.swift b/ShenYin/ShenYin/Sdk/JoySdk/VC/JoyStereoCallVC.swift
similarity index 99%
rename from ShenYin/ShenYin/UI/Home/StereoCallVC.swift
rename to ShenYin/ShenYin/Sdk/JoySdk/VC/JoyStereoCallVC.swift
index 146ff75..085d94e 100644
--- a/ShenYin/ShenYin/UI/Home/StereoCallVC.swift
+++ b/ShenYin/ShenYin/Sdk/JoySdk/VC/JoyStereoCallVC.swift
@@ -1,5 +1,5 @@
//
-// StereoCallVC.swift
+// JoyStereoCallVC.swift
// ShenYin
//
// Created by liangshi on 2025/11/26.
@@ -7,7 +7,7 @@
import UIKit
import AVFAudio
-class StereoCallVC:BaseVC{
+class JoyStereoCallVC:BaseVC{
let toolBar = FieldRecordBar()
let line = UIView()
let selfTextView = UITextView()
@@ -196,7 +196,7 @@ class StereoCallVC:BaseVC{
}
}
-extension StereoCallVC:FieldRecordBarDelegate{
+extension JoyStereoCallVC:FieldRecordBarDelegate{
func fieldRecordBar(_ bar: FieldRecordBar, languageChange language: CCAiLanguage) {
JoySdkManager.shared.callRecord.setCallRecoordLanage(language)
AiLanguageCache.save(type: .thly, lan: language)
diff --git a/ShenYin/ShenYin/Sdk/JoySdk/VC/JoyTctyVC.swift b/ShenYin/ShenYin/Sdk/JoySdk/VC/JoyTctyVC.swift
new file mode 100644
index 0000000..5931db3
--- /dev/null
+++ b/ShenYin/ShenYin/Sdk/JoySdk/VC/JoyTctyVC.swift
@@ -0,0 +1,155 @@
+//
+// JoyDctyVC.swift
+// ShenYin
+//
+// Created by liangshi on 2025/8/6.
+//
+
+import UIKit
+import AVFoundation
+class JoyTctyVC:BaseVC{
+ let toolBar = RecordBar()
+ let textView = PlaceHolderTextView()
+ let translateTextView = PlaceHolderTextView()
+ let sdk = JoyTcty()
+
+ deinit {
+ CCAiManager.stopPlay()
+ }
+ override func setupViews() {
+ view.addSubviews([toolBar,textView,translateTextView])
+ navBar.title = "åä¼ å¬è¯".l10n
+ navBar.rightView.isHidden = false
+ navBar.rightView.setImage(UIImage(named: "help_icon"), for: .normal)
+
+ toolBar.do { v in
+ v.backgroundColor = .clear
+ v.delegate = self
+ v.recordBtn.activeView.backgroundColor = .hexString("#F7F7F7")
+ v.leftItem.valueLabel.text = "ææº".l10n
+ v.leftItem.language = AiLanguageCache.get(type: .tscy_left) ?? .chinse
+ v.rightItem.language = AiLanguageCache.get(type: .tscy_right) ?? .english
+ }
+ view.backgroundColor = .hexString("#F7F7F7")
+
+ textView.do { v in
+ v.placeHolde = "æ¤å¤å°æ¾ç¤ºåæ".l10n
+ v.textView.textColor = .hexString("#666666")
+ }
+ translateTextView.do { v in
+ v.textView.textColor = .hexString("#121212")
+ v.placeHolde = "æ¤å¤å°æ¾ç¤ºè¯æ".l10n
+ v.bgView.yc.addgradientLayer(colors: [.hexString("#0092E1"),.hexString("#F7F7F7")], direction: .top2down,rect: CGRect(x: 0, y: 0, width: kScreenWid, height: (kScreenHei - kNavBtm - 120 - 10)/2))
+ v.bgView.alpha = 0.1
+ v.yc.setCorners(withRoundedRect: CGRect(x: 0, y: 0, width: kScreenWid, height: (kScreenHei - kNavBtm - 120 - 10)/2), roundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 20, height: 20))
+ }
+ }
+ override func setupLayout() {
+ toolBar.snp.makeConstraints { make in
+ make.width.centerX.equalToSuperview()
+ make.height.equalTo(120)
+ make.bottom.equalToSuperview().inset(20)
+ }
+ textView.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(80)
+ make.left.right.equalToSuperview()
+ make.height.equalTo((kScreenHei - kNavBtm - 120 - 10)/2)
+ }
+ translateTextView.snp.makeConstraints { make in
+ make.top.equalTo(textView.snp.bottom).offset(10)
+ make.left.right.equalToSuperview()
+ make.bottom.equalTo(toolBar.snp.top)
+ }
+ }
+ override func setupData() {
+ if TipsCache.needShow(type: .tongchuan) {
+ RecordTipsView(type: .tongchuan).show()
+ }
+
+ sdk.stopCallback = {[weak self] in
+ guard let self = self else{return}
+ toolBar.recordBtn.isSelected = false
+ }
+ sdk.refreshOriginCallback = {[weak self] text in
+ guard let self = self else{return}
+ textView.text = text
+ textView.textView.scrollToBottom()
+ }
+ sdk.refreshTranslateCallback = {[weak self] text in
+ guard let self = self else{return}
+ translateTextView.text = text
+ translateTextView.textView.scrollToBottom()
+ }
+ sdk.filePathCallback = { [weak self] path in
+ guard let self = self else{return}
+ guard let wavPath = DCFolder.recordFileResave(srcPath: path) else{return}
+ let v = PopTextField()
+ v.show()
+ v.cancelTap = {
+ App.shared.popPage()
+ }
+ v.okTap = { [weak self] text in
+ guard let self = self else{return}
+
+ let model = RecordDetailModel()
+ model.type = .translate
+ model.from = toolBar.leftItem.language
+ model.to = toolBar.rightItem.language
+ model.name = text
+ model.path = wavPath
+ model.duration = YLToos.getDuration(model.path)
+ model.origin = textView.text ?? ""
+ model.translate = translateTextView.text ?? ""
+ App.shared.popPage(animated: false)
+ App.shared.goToPage(RecordDetailVC(record: model))
+ }
+ }
+ }
+ override func navRightViewTapped() {
+ let tip = RecordTipsView(type: .tongchuan)
+ tip.show()
+ }
+
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+ navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = false
+
+ PcmSound.sharedInstance().delegate = sdk
+ CCAiManager.preparePlayBlueTooth()
+ }
+ override func viewDidDisappear(_ animated: Bool) {
+ super.viewDidDisappear(animated)
+ navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = true
+ CCAiManager.stopPlay()
+ }
+ override func navleftViewTapped() {
+ if toolBar.recordBtn.isSelected {
+ CustomAlert.showWith(title: "æç¤º".l10n, messgage: "å½åæ£å¨å½é³ï¼ç¡®å®æ¾å¼å½åå½é³åï¼".l10n, cancelCallback: {}) {
+ self.sdk.stop()
+ CCAiManager.stopPlay()
+ super.navleftViewTapped()
+ }
+ }
+ else{
+ super.navleftViewTapped()
+ }
+ }
+}
+
+extension JoyTctyVC:RecordBarDelegate{
+ func recordBarLanguageChange(_ bar:RecordBar){
+ AiLanguageCache.save(type: .tscy_left, lan: bar.leftItem.language)
+ AiLanguageCache.save(type: .tscy_right, lan: bar.rightItem.language)
+ }
+ func recordBar(_ bar: RecordBar, stateChange state: RecordBarSate) {
+ if state == .start {
+ textView.text = nil
+ translateTextView.text = nil
+ sdk.start(from: toolBar.leftItem.language.value, to: toolBar.rightItem.language.value)
+ }
+ else if state == .stop{
+ sdk.stop()
+ bar.startAnimating()
+ }
+ }
+}
diff --git a/ShenYin/ShenYin/UI/Home/FieldRecording/FieldRecordingVC.swift b/ShenYin/ShenYin/Sdk/JoySdk/VC/JoyXclyVC.swift
similarity index 97%
rename from ShenYin/ShenYin/UI/Home/FieldRecording/FieldRecordingVC.swift
rename to ShenYin/ShenYin/Sdk/JoySdk/VC/JoyXclyVC.swift
index 2a41fb7..7d4fb97 100644
--- a/ShenYin/ShenYin/UI/Home/FieldRecording/FieldRecordingVC.swift
+++ b/ShenYin/ShenYin/Sdk/JoySdk/VC/JoyXclyVC.swift
@@ -7,7 +7,7 @@
import UIKit
import AVFAudio
-class FieldRecordingVC:BaseVC{
+class JoyXclyVC:BaseVC{
let toolBar = FieldRecordBar()
let textView = UITextView()
let rhythView = RhythView()
@@ -68,7 +68,6 @@ class FieldRecordingVC:BaseVC{
func setupSdk() {
JoySdkManager.shared.record.recordFinish = {[weak self] path in
guard let self = self else { return }
- Logger.debug("0000000 ===",textView.text ?? "")
if !needSave {
return
}
@@ -133,7 +132,7 @@ class FieldRecordingVC:BaseVC{
}
}
-extension FieldRecordingVC:FieldRecordBarDelegate{
+extension JoyXclyVC:FieldRecordBarDelegate{
func fieldRecordBar(_ bar: FieldRecordBar, languageChange language: CCAiLanguage) {
JoySdkManager.shared.record.setRecoordLanage(language)
AiLanguageCache.save(type: .xcly, lan: language)
diff --git a/ShenYin/ShenYin/UI/Home/Chat/ChatNavigationBarItem.swift b/ShenYin/ShenYin/UI/Home/Chat/ChatNavigationBarItem.swift
index a8766c9..3b0eeac 100644
--- a/ShenYin/ShenYin/UI/Home/Chat/ChatNavigationBarItem.swift
+++ b/ShenYin/ShenYin/UI/Home/Chat/ChatNavigationBarItem.swift
@@ -5,7 +5,6 @@
// Created by liangshi on 2025/9/3.
//
import UIKit
-import JoyGemAI
class ChatNavigationBarItem: BaseView {
let icon = UIImageView()
@@ -44,7 +43,7 @@ class ChatRoleItem: BaseView {
let icon = UIImageView()
let titleLabel = UILabel()
let deslabel = UILabel()
- var role:JoyGemSpeaker!{
+ var role:CCRole!{
didSet{
titleLabel.text = role.name
icon.image = UIImage(named: "role_" + role.role)
diff --git a/ShenYin/ShenYin/UI/Home/Chat/RoleListVC.swift b/ShenYin/ShenYin/UI/Home/Chat/RoleListVC.swift
index c791423..38600de 100644
--- a/ShenYin/ShenYin/UI/Home/Chat/RoleListVC.swift
+++ b/ShenYin/ShenYin/UI/Home/Chat/RoleListVC.swift
@@ -6,14 +6,13 @@
//
import UIKit
-import JoyGemAI
class RoleListVC: BaseVC{
let tableView = UITableView(frame: .zero, style: .plain)
- let list:[JoyGemSpeaker]
- let selectedModel:JoyGemSpeaker
- var didSelected:((JoyGemSpeaker)->Void)?
+ let list:[CCRole]
+ let selectedModel:CCRole
+ var didSelected:((CCRole)->Void)?
- init(list: [JoyGemSpeaker], selectedModel: JoyGemSpeaker, didSelected: ((JoyGemSpeaker) -> Void)? = nil) {
+ init(list: [CCRole], selectedModel: CCRole, didSelected: ((CCRole) -> Void)? = nil) {
self.list = list
self.selectedModel = selectedModel
self.didSelected = didSelected
@@ -87,7 +86,7 @@ class RoleListCell: BaseTableViewCell {
let titleLabel = UILabel()
let selectedIcon = UIImageView()
let line = UIView()
- var data:JoyGemSpeaker!{
+ var data:CCRole!{
didSet{
titleLabel.text = data.name
icon.image = UIImage(named: "role_" + data.role)
diff --git a/ShenYin/ShenYin/UI/Home/RecordTranslateVC.swift b/ShenYin/ShenYin/UI/Home/RecordTranslateVC.swift
deleted file mode 100644
index 9f0127a..0000000
--- a/ShenYin/ShenYin/UI/Home/RecordTranslateVC.swift
+++ /dev/null
@@ -1,242 +0,0 @@
-//
-// RecordTranslateVC.swift
-// ShenYin
-//
-// Created by liangshi on 2025/8/6.
-//
-
-import UIKit
-import JoyGemAI
-import AVFoundation
-class RecordTranslateVC:BaseVC{
- let toolBar = RecordBar()
- let textView = PlaceHolderTextView()
- let translateTextView = PlaceHolderTextView()
- var messageList : [(String,UInt)] = []
- var translateList : [(String,UInt)] = []
- var recordFilePath : String?
-
- deinit {
- PcmSound.sharedInstance().stopAudioUnit()
- PcmSound.sharedInstance().cleanup()
- }
- override func setupViews() {
- view.addSubviews([toolBar,textView,translateTextView])
-
- navBar.title = "åä¼ å¬è¯".l10n
- navBar.rightView.isHidden = false
- navBar.rightView.setImage(UIImage(named: "help_icon"), for: .normal)
-
- toolBar.do { v in
- v.backgroundColor = .clear
- v.delegate = self
- v.recordBtn.activeView.backgroundColor = .hexString("#F7F7F7")
- v.leftItem.valueLabel.text = "ææº".l10n
- v.leftItem.language = AiLanguageCache.get(type: .tscy_left) ?? .chinse
- v.rightItem.language = AiLanguageCache.get(type: .tscy_right) ?? .english
- }
- view.backgroundColor = .hexString("#F7F7F7")
-
- textView.do { v in
- v.placeHolde = "æ¤å¤å°æ¾ç¤ºåæ".l10n
- v.textView.textColor = .hexString("#666666")
- }
- translateTextView.do { v in
- v.textView.textColor = .hexString("#121212")
- v.placeHolde = "æ¤å¤å°æ¾ç¤ºè¯æ".l10n
- v.bgView.yc.addgradientLayer(colors: [.hexString("#0092E1"),.hexString("#F7F7F7")], direction: .top2down,rect: CGRect(x: 0, y: 0, width: kScreenWid, height: (kScreenHei - kNavBtm - 120 - 10)/2))
- v.bgView.alpha = 0.1
- v.yc.setCorners(withRoundedRect: CGRect(x: 0, y: 0, width: kScreenWid, height: (kScreenHei - kNavBtm - 120 - 10)/2), roundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 20, height: 20))
- }
- }
- override func setupLayout() {
- toolBar.snp.makeConstraints { make in
- make.width.centerX.equalToSuperview()
- make.height.equalTo(120)
- make.bottom.equalToSuperview().inset(20)
- }
- textView.snp.makeConstraints { make in
- make.top.equalToSuperview().inset(80)
- make.left.right.equalToSuperview()
- make.height.equalTo((kScreenHei - kNavBtm - 120 - 10)/2)
- }
- translateTextView.snp.makeConstraints { make in
- make.top.equalTo(textView.snp.bottom).offset(10)
- make.left.right.equalToSuperview()
- make.bottom.equalTo(toolBar.snp.top)
- }
- }
- override func setupData() {
- JoyGemSIManager.shared().delegate = self
-
- PcmSound.sharedInstance().delegate = self;
- do {
- try AVAudioSession.sharedInstance().setCategory(.playback)
- try AVAudioSession.sharedInstance().setActive(true)
- } catch {
- Logger.debug(error)
- }
- PcmSound.sharedInstance().setup(16000, withchannels: 1)
-
- if TipsCache.needShow(type: .tongchuan) {
- RecordTipsView(type: .tongchuan).show()
- }
- }
- override func navRightViewTapped() {
- let tip = RecordTipsView(type: .tongchuan)
- tip.show()
- }
-
- override func viewDidAppear(_ animated: Bool) {
- super.viewDidAppear(animated)
- navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = false
- }
- override func viewDidDisappear(_ animated: Bool) {
- super.viewDidDisappear(animated)
- navigationController?.fd_fullscreenPopGestureRecognizer?.isEnabled = true
-
- PcmSound.sharedInstance().stopAudioUnit()
- PcmSound.sharedInstance().cleanup()
- }
- override func navleftViewTapped() {
- if toolBar.recordBtn.isSelected {
- CustomAlert.showWith(title: "æç¤º".l10n, messgage: "å½åæ£å¨å½é³ï¼ç¡®å®æ¾å¼å½åå½é³åï¼".l10n, cancelCallback: {}) {
- JoyGemSIManager.shared().stop()
- PcmSound.sharedInstance().stopAudioUnit()
- PcmSound.sharedInstance().cleanup()
- super.navleftViewTapped()
- }
- }
- else{
- super.navleftViewTapped()
- }
- }
-}
-
-extension RecordTranslateVC:RecordBarDelegate{
- func recordBarLanguageChange(_ bar:RecordBar){
- AiLanguageCache.save(type: .tscy_left, lan: bar.leftItem.language)
- AiLanguageCache.save(type: .tscy_right, lan: bar.rightItem.language)
- }
- func recordBar(_ bar: RecordBar, stateChange state: RecordBarSate) {
- if state == .start {
- messageList.removeAll()
- translateList.removeAll()
- textView.text = nil
- translateTextView.text = nil
-
- if Thread.isMainThread {
- do {
- try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [])
- try AVAudioSession.sharedInstance().setActive(true)
- } catch let error as NSError {
- Logger.debug("An error occurred setting the audio session category: \(error.localizedDescription)")
- }
- } else {
- DispatchQueue.main.sync {
- do {
- try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [])
- try AVAudioSession.sharedInstance().setActive(true)
- } catch let error as NSError {
- Logger.debug("An error occurred setting the audio session category: \(error.localizedDescription)")
- }
- }
- }
- JoyGemSIManager.shared().originalLanguage = toolBar.leftItem.language.value
- JoyGemSIManager.shared().targetLanguage = toolBar.rightItem.language.value
- JoyGemSIManager.shared().start()
- }
- else if state == .stop{
- JoyGemSIManager.shared().stop()
- bar.startAnimating()
- }
- }
-}
-
-extension RecordTranslateVC : JoyGemSIManagerDelegate {
- func siManagerStopped(_ manager: JoyGemSIManager, reason code: JoyGemRecordStopCode) {
- if (code == .actively) {
-// YLprogressHUD.showAutoHiden("ç¨æ·ä¸»å¨ç»æ")
- } else {
- toolBar.recordBtn.isSelected = false
- }
- }
-
- func siManager(_ manager: JoyGemSIManager, didUpdateRaw model: JoyGemAsrModel) {
- let msg = messageList.firstIndex (where: { (str,idx) in
- return idx == model.index;
- })
- if (msg == nil) {
- messageList.append((model.text,model.index))
- } else {
- messageList[msg!] = (model.text,model.index)
- }
-
- textView.text = messageList.compactMap({ (str,idx) in
- return str
- }).joined(separator: "\n")
- textView.textView.scrollToBottom()
- }
-
- func siManager(_ manager: JoyGemSIManager, didUpdateTranslate model: JoyGemAsrModel) {
- Logger.debug("translate text: \(model.text),index: \(model.index)")
- let msg = translateList.firstIndex (where: { (str,idx) in
- return idx == model.index;
- })
- if (msg == nil) {
- translateList.append((model.text,model.index))
- } else {
- translateList[msg!] = (model.text,model.index)
- }
-
- translateTextView.text = translateList.compactMap({ (str,idx) in
- return str
- }).joined(separator: "\n")
- translateTextView.textView.scrollToBottom()
- }
-
-
- func siManager(_ manager: JoyGemSIManager, saveFile path: String) {
- Logger.debug("path: \(path)")
- recordFilePath = path
- guard let path = recordFilePath,let wavPath = DCFolder.recordFileResave(srcPath: path) else{return}
- let v = PopTextField()
- v.show()
- v.cancelTap = {
- App.shared.popPage()
- }
- v.okTap = { [weak self] text in
- guard let self = self else{return}
-
- let model = RecordDetailModel()
- model.type = .translate
- model.from = toolBar.leftItem.language
- model.to = toolBar.rightItem.language
- model.name = text
- model.path = wavPath
- model.duration = YLToos.getDuration(model.path)
- model.origin = textView.text ?? ""
- model.translate = translateTextView.text ?? ""
- App.shared.popPage(animated: false)
- App.shared.goToPage(RecordDetailVC(record: model))
- }
- }
-
- func siManager(_ manager: JoyGemSIManager, stateChange code: JoyGemStateCode) {
- Logger.debug("code: \(code)")
- }
-
- func siManager(_ manager: JoyGemSIManager, didUpdateAudioData data: Data, sampleRate: UInt) {
- PcmSound.sharedInstance().feed(data)
- }
- func siManager(_ manager: JoyGemSIManager, onError code: JoyGemErrorCode) {
-
- }
-}
-
-extension RecordTranslateVC : PcmSoundDelegate {
-
- func remaining(_ frames: UInt) {
- Logger.debug("[frame:\(frames)]");
- }
-}
diff --git a/ShenYin/ShenYin/UI/Home/Root/HomeFunctionView.swift b/ShenYin/ShenYin/UI/Home/Root/HomeFunctionView.swift
index 6a0367d..0ded13c 100644
--- a/ShenYin/ShenYin/UI/Home/Root/HomeFunctionView.swift
+++ b/ShenYin/ShenYin/UI/Home/Root/HomeFunctionView.swift
@@ -185,20 +185,15 @@ class HomeCell: BaseView {
}
switch type {
case .fileRecord:
- App.shared.goToPage(FieldRecordingVC())
+ CCPage.gotoFieldRecord()
case .callRecord:
- if JoySdkManager.shared.callRecord.supportStereo{
- App.shared.goToPage(StereoCallVC())
- }
- else{
- App.shared.goToPage(CallingRecordVC())
- }
+ CCPage.gotoCallRecord()
case .chinese2English:
- App.shared.goToPage(Chinese2EnglishVC())
+ CCPage.gotoChinese2Enlgish()
case .recordTranslate:
- App.shared.goToPage(RecordTranslateVC())
+ CCPage.gotoTcty()
case .dialogTranslate:
- App.shared.goToPage(DialogTranslateVC())
+ CCPage.gotoDialogTranslate()
case .textTranslate:
App.shared.goToPage(TextTranlateVC())
}
diff --git a/ShenYin/ShenYin/UI/Home/Root/HomeHeadView.swift b/ShenYin/ShenYin/UI/Home/Root/HomeHeadView.swift
index fcc0708..95a57fa 100644
--- a/ShenYin/ShenYin/UI/Home/Root/HomeHeadView.swift
+++ b/ShenYin/ShenYin/UI/Home/Root/HomeHeadView.swift
@@ -88,7 +88,7 @@ class HomeHeadView: BaseView {
}
@objc func chatAction(){
if CCBleManager.shared.isConnetd {
- App.shared.goToPage(ChatVC())
+ CCPage.gotoChat()
}
}
@objc func deviceChange(_ noti:Notification){
diff --git a/ShenYin/ShenYin/UI/Home/TextTranslate/TextTranslateVC.swift b/ShenYin/ShenYin/UI/Home/TextTranslate/TextTranslateVC.swift
index e58eefe..1af0ed4 100644
--- a/ShenYin/ShenYin/UI/Home/TextTranslate/TextTranslateVC.swift
+++ b/ShenYin/ShenYin/UI/Home/TextTranslate/TextTranslateVC.swift
@@ -6,7 +6,7 @@
//
import UIKit
-import JoyGemAI
+
class TextTranlateVC:BaseVC{
let scrollView = UIScrollView()
let languageItem = LanguageSelectItem()
@@ -95,16 +95,14 @@ extension TextTranlateVC:SendToolBarDelegate{
let from = languageItem.leftLabel.language.value
let to = languageItem.rightLabel.language.value
- JoyGemAIManager.shared().translate(text, from: from, to: to) {[weak self] result, finish in
+ CCAiManager.translate(text:text, from: from, to: to) { [weak self] response in
guard let self = self else{return}
+ guard let (result, finish) = response else{return}
if !finish{
dataList.last!.response = dataList.last!.response + result
refreshData()
}
- } error: { error in
-
}
-
}
}