+++ /dev/null
-//
-// Record.swift
-// Example
-//
-// Created by liangshi on 2025/12/19.
-//
-//import DeepChordsSdk
-//
-//class DCRecordManager{
-// static let shared = DCRecordManager()
-//
-// func setupRecord(){
-// DCBleRecord.shared.codeCallback = { [weak self] code in
-// guard let self = self else{return}
-// if code == 20001 {
-// if let vc = App.shared.topVC() as? EarPhoneRecordVC {
-// // vc.startRecord()
-// }else{
-// App.shared.goToPage(EarPhoneRecordVC())
-// }
-// }
-// else if code == 20002 || code == 20003{
-//// self.recordBtn.isSelected = false
-// }
-//
-// }
-// }
-//}
+++ /dev/null
-//
-// Untitled.swift
-// Example
-//
-// Created by liangshi on 2025/12/15.
-//
-
-import Foundation
-import AVFoundation
-
-class PlayerManager:NSObject{
- public static let shared = PlayerManager()
- private var finishCallback:((_ success:Bool,_ dialoIg:Int) -> Void)?
- var dialoIg = 0
-
- private override init() {
- super.init()
- }
-
- var player = AVAudioPlayer()
-
- func play(filePath:String,dialoIg:Int,finished: ((_ success: Bool,_ dialoIg:Int) -> Void)? = nil) {
- self.dialoIg = dialoIg
- print("声音播放: \(filePath)")
- self.finishCallback = finished
- let url = URL(fileURLWithPath: filePath)
- do {
- try player = AVAudioPlayer(contentsOf: url)
- player.prepareToPlay()
- player.delegate = self
- player.play()
- } catch let error as NSError {
- print("声音播放失败 \(error.description)")
- self.finishCallback?(false,dialoIg)
- }
- }
-
- func stop(){
- if player.isPlaying{
- player.stop()
- }
- }
-}
-
-extension PlayerManager:AVAudioPlayerDelegate{
- func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
- print("播放结束 \(flag)")
- self.finishCallback?(true,self.dialoIg)
- }
-
- func audioPlayerDecodeErrorDidOccur(_ player: AVAudioPlayer, error: Error?) {
- if let error = error {
- print("解码错误: \(error.localizedDescription)")
- }
- self.finishCallback?(false,self.dialoIg)
- }
-}
-
-
objects = {
/* Begin PBXBuildFile section */
+ 3F7602F12EFA8BAB00588C18 /* DeepChordsSdk.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F7602EA2EFA891200588C18 /* DeepChordsSdk.framework */; };
+ 3F7602F22EFA8BAB00588C18 /* DeepChordsSdk.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3F7602EA2EFA891200588C18 /* DeepChordsSdk.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
3F79C6142E6055E500EC38B9 /* JoyGemAI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F79C4902E603B4700EC38B9 /* JoyGemAI.framework */; };
3F79C6152E6055E500EC38B9 /* JoyGemAI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3F79C4902E603B4700EC38B9 /* JoyGemAI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
3F8F58292EBCA2B800FFC00B /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 3F8F58282EBCA2B800FFC00B /* PrivacyInfo.xcprivacy */; };
dstPath = "";
dstSubfolderSpec = 10;
files = (
+ 3F7602F22EFA8BAB00588C18 /* DeepChordsSdk.framework in Embed Frameworks */,
3F79C6152E6055E500EC38B9 /* JoyGemAI.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
/* Begin PBXFileReference section */
3862D5561144E20721225B96 /* Pods_ShenYin.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ShenYin.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 3F7602EA2EFA891200588C18 /* DeepChordsSdk.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DeepChordsSdk.framework; sourceTree = BUILT_PRODUCTS_DIR; };
3F79C4902E603B4700EC38B9 /* JoyGemAI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = JoyGemAI.framework; sourceTree = "<group>"; };
3F887B9C2E38D8DC00C98658 /* ShenYin.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ShenYin.app; sourceTree = BUILT_PRODUCTS_DIR; };
3F8F58282EBCA2B800FFC00B /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
buildActionMask = 2147483647;
files = (
F2E449CAD5874BE652A69B50 /* Pods_ShenYin.framework in Frameworks */,
+ 3F7602F12EFA8BAB00588C18 /* DeepChordsSdk.framework in Frameworks */,
3F79C6142E6055E500EC38B9 /* JoyGemAI.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
676B86A4BA2639E8694D56B4 /* Frameworks */ = {
isa = PBXGroup;
children = (
+ 3F7602EA2EFA891200588C18 /* DeepChordsSdk.framework */,
3F79C4902E603B4700EC38B9 /* JoyGemAI.framework */,
3862D5561144E20721225B96 /* Pods_ShenYin.framework */,
);
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
+ <FileRef
+ location = "container:../DeepChordsSdk_iOS/DeepChordsSdk/Example/Example.xcodeproj">
+ </FileRef>
</Workspace>
--- /dev/null
+//
+// DCChatManager.swift
+// Example
+//
+// Created by liangshi on 2025/12/15.
+//
+import AVFoundation
+import DeepChordsSdk
+//typedef NS_OPTIONS(NSInteger,StarburstCode) {
+// StarburstCode_Start_Record = 20001,///开始录音
+// StarburstCode_Stop_Record = 20002,///停止录音
+// StarburstCode_Record_Error = 20003,///录音出错
+// StarburstCode_Ble_Disconected = 20004,///蓝牙断开
+// StarburstCode_Websocket_Connected = 30001,///socket连上
+// StarburstCode_Websocket_Disconnected = 30002,///socket断开连接
+// StarburstCode_Websocket_Connecting = 30003,///socket连接中...
+// StarburstCode_Websocket_pingTimeOut = 30004,///ping超时
+// StarburstCode_Net_Error = 50000,///网络错误
+// StarburstCode_UnAuth = 60000,///未鉴权
+//};
+
+
+class DCChatManager:NSObject{
+ static let shared = DCChatManager()
+ private var isTtsPlaying = false
+ private var audioData: Data?
+
+ public var dataList:[ChatCellModel] = []
+ public var chatNeedReloadData:(()->Void)?
+ /// 状态码回调
+ public var codeCallback:((Int)->Void)?
+ /// 结束对话回调
+ public var finishCallback:((String?)->Void)?
+
+ var role:DCRole? {
+ didSet{
+ setupChat()
+ }
+ }
+
+ public func stopChat(){
+ DCChat.shared.stopChat()
+ }
+ 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)
+ }
+ }
+
+ func setupChat(){
+ preparePlay()
+ DCChat.shared.role = role
+ DCChat.shared.asrCallback = {[weak self] (text,index) in
+ guard let self = self else{return}
+ if let model = dataList.last,model.id == index,model.type == 1 {
+ model.content = text
+ }
+ else{
+ let model = ChatCellModel()
+ model.type = 1
+ model.content = text
+ model.id = Int(index)
+ dataList.append(model)
+ }
+ chatNeedReloadData?()
+ }
+ DCChat.shared.responseCallback = { [weak self] (text,index) in
+ guard let self = self else{return}
+ if let model = dataList.last,model.id == index,model.type == 2 {
+ model.content = text
+ }
+ else{
+ let model = ChatCellModel()
+ model.type = 2
+ model.content = text
+ model.id = Int(index)
+ dataList.append(model)
+ }
+ chatNeedReloadData?()
+ }
+ DCChat.shared.dataCallback = {[weak self] (dialogId, data, finish,sampleRate) in
+ PcmSound.sharedInstance().delegate = self
+ guard let self = self else { return }
+ if (!isTtsPlaying) {
+ isTtsPlaying = true
+ DCLogger.debug("开始播放")
+ DCChat.shared.startPlayTtsAudio()
+ }
+ DCLogger.debug("收到音频数据", data?.count ?? 0,sampleRate)
+ PcmSound.sharedInstance().feed(data)
+ }
+ DCChat.shared.codeCallback = {[weak self] code in
+ guard let self = self else { return }
+ self.codeCallback?(code)
+
+ if code == 20001 {
+ if (self.isTtsPlaying) {
+ self.isTtsPlaying = false
+ 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)
+ }
+ }
+ }
+ }
+ DCChat.shared.finishCallback = {[weak self] path in
+ self?.preparePlay()
+ self?.finishCallback?(path)
+ }
+
+ }
+
+// func saveToFile(data: Data) {
+// let filePath = NSHomeDirectory() + "/Documents/1.mp3"
+// let url = URL(fileURLWithPath: filePath)
+// do {
+// try data.write(to: url)
+// print("\(filePath)")
+//
+// var options: AVAudioSession.CategoryOptions = [.allowBluetooth]
+// do {
+// try AVAudioSession.sharedInstance().setCategory(.playback, options: [options])
+// try AVAudioSession.sharedInstance().setActive(true)
+// } catch {
+// DCLogger.debug(error)
+// }
+// //这个要传开始播放的tts的dialogid
+// DCChat.shared.startPlayTtsAudio()
+// PlayerManager.shared.play(filePath: filePath,dialoIg:0) { (success,dialoIg) in
+// print("播放结束 = \(success)")
+// DCChat.shared.stopPlayTtsAudio()
+// }
+// } catch let error {
+// print("\(error)")
+// }
+// }
+}
+extension DCChatManager : PcmSoundDelegate {
+ func remaining(_ frames: UInt) {
+ DCLogger.debug("[frame:\(frames)]");
+ if (frames == 0) {
+ DCChat.shared.stopPlayTtsAudio()
+ }
+ }
+}
--- /dev/null
+//
+// DCSdkManager.swift
+// Example
+//
+// Created by liangshi on 2025/12/19.
+//
+import DeepChordsSdk
+
+class DCSdkManager{
+ static let shared = DCSdkManager()
+
+
+ func initSdk(){
+ DeepChordsAiSdk.shared.initSDK()
+// DCRecordManager.shared.setupRecord()
+ DCChatManager.shared.setupChat()
+
+ DCDevice.shared.eventCallback = { event in
+ switch event {
+ case 0x01:
+// if let vc = App.shared.topVC() as? ChatVC {
+// // vc.startRecord()
+// }else{
+// App.shared.goToPage(ChatVC())
+// }
+ break
+ case 0x02:
+// if let vc = App.shared.topVC() as? ChatVC {
+// // vc.startRecord()
+// }else{
+// App.shared.goToPage(ChatVC())
+// }
+ break
+ case 0x03:
+// if let vc = App.shared.topVC() as? EarPhoneRecordVC {
+// // vc.startRecord()
+// }else{
+// App.shared.goToPage(EarPhoneRecordVC())
+// }
+ break
+ case 0x04:
+// if let vc = App.shared.topVC() as? EarPhoneRecordVC {
+// // vc.startRecord()
+// }else{
+// App.shared.goToPage(EarPhoneRecordVC())
+// }
+ break
+ default:
+ break
+ }
+ }
+ }
+}
--- /dev/null
+////
+//// JotBleManager.swift
+//// ShenYin
+////
+//// Created by liangshi on 2025/12/23.
+////
+//
+//public class JoyBleManager {
+// public static let shared = JoyBleManager()
+// private var connectPeripheral: CBPeripheral?
+// private var writeCha: CBCharacteristic?
+//}
+//extension JoyBleManager{
+// static func getMac(_ dict:[String:Any])->String?{
+// if let advMsd = dict[CBAdvertisementDataManufacturerDataKey] as? Data {
+// if (advMsd.count >= 13) {
+// let mac = advMsd[7...12];
+// return mac.map { String($0, radix: 16).padLeft(toLength: 2, withPad: "0") }.joined(separator: ":").uppercased()
+// } else {
+// return nil
+// }
+// } else {
+// return nil
+// }
+// }
+//}
+////public extension JoyBleManager{
+//// func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
+//// Logger.debug("蓝牙已连接 \(peripheral)")
+//// connectPeripheral = peripheral
+//// }
+//// func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
+//// Logger.debug("peripheral: %@ failed to connect", peripheral)
+//// }
+//// func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
+//// Logger.debug("蓝牙已断开 \(peripheral)")
+//// }
+////
+////// func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
+////// Logger.debug("发现服务成功")
+////// for service in peripheral.services! {
+////// Logger.debug("peripheral service: %@", service)
+////// peripheral.discoverCharacteristics(nil, for: service)
+////// }
+//////
+////// }
+////// func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
+////// if let list = service.characteristics{
+////// Logger.debug("发现特征",list)
+////// for char in list{
+////// Logger.debug(char)
+////// peripheral.setNotifyValue(true, for: char)
+////// if char.uuid.uuidString == "AE03" {
+////// writeCha = char
+////// StarburstSdk.shared().bleConnected()
+////// }
+////// }
+////// }
+////// }
+//////
+////// func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
+////// // Logger.debug("收 ",characteristic.uuid,characteristic.value?.joined() ?? "")
+////// guard let data = characteristic.value else { return }
+////// if data.count > 4 && data[0] == 0xBA {
+////// if let sender = BleSender.answer(data) {
+////// sender.completion?(.response.code(.success).value(data))
+////// if data[1] == 0x10,data[2] == 0x01{
+////// //音乐列表分包,解析的时候处理
+////// }
+////// else{
+////// sender.deinitTimer()
+////// sender.remove()
+////// }
+////// return
+////// }
+////// else if data[1] == 0x0D{
+////// let subData = data.subdata(in: 2..<data.count - 3)
+////// //Logger.debug("传给字节sdk",subData.joined())
+////// StarburstSdk.shared().receiveBleData(subData)
+////// }else{
+////// receiveNoticeData(data)
+////// }
+////// }
+////// else{
+////// Logger.debug("收到异常数据!!!!!!!!!!!")
+////// }
+////// }
+////}
func setupLog(){
//MARK: 配置日志类型
- //JoyGemAIManager.shared().setLogMode(JoyGemLogMode.all)
- JoyGemAIManager.shared().setLogMode(JoyGemLogMode.close)
+ JoyGemAIManager.shared().setLogMode(.close)
let fileManager = FileManager.default
if let appSupportDirectory = fileManager.urls(for: .applicationSupportDirectory, in: .userDomainMask).first {
func bleConnected(){
JoyGemAIManager.shared().bleConnected()
}
+ func bleDisConnected(){
+ JoyGemAIManager.shared().bleDisConnected()
+ }
func receiveValue(_ characteristic:CBCharacteristic){
JoyGemAIManager.shared().receiveValue(characteristic)
}
extension JoySdkManager{
- static func getMac(_ dict:[String:Any])->String?{
+ static func getMac(_ dict:[String:Any])->String?{
if let advMsd = dict[CBAdvertisementDataManufacturerDataKey] as? Data {
if (advMsd.count >= 13) {
let mac = advMsd[7...12];
Logger.debug(DCFolder.record)
window?.rootViewController = BaseTC()
JoySdkManager.shared.chat.loadChatCache()
+// DCSdkManager.shared.initSdk()
}
func goToLogin(){
window?.rootViewController = BaseNC(rootViewController: LoginVC())
func setupUI(){
- let item0 = UITabBarItem(title: "智能".l10n + " " + "AI", image: UIImage(named: "tab_0_normal")?.withRenderingMode(.alwaysOriginal), selectedImage: UIImage(named: "tab_0_selected")?.withRenderingMode(.alwaysOriginal))
+ let item0 = UITabBarItem(title: "AI" + " " + "智能".l10n , image: UIImage(named: "tab_0_normal")?.withRenderingMode(.alwaysOriginal), selectedImage: UIImage(named: "tab_0_selected")?.withRenderingMode(.alwaysOriginal))
let nc0 = BaseNC(rootViewController: homeVC)
nc0.tabBarItem = item0