From: liangzhenying <867174124@qq.com> Date: Mon, 15 Dec 2025 09:14:44 +0000 (+0800) Subject: 骨传导调试 X-Git-Tag: 1.0.2~35 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=5bd7739bfc8dfef89f4eadb93c77bb0ac2b042d6;p=mirrors%2FShenYin.git 骨传导调试 --- diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCBleRecord.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCBleRecord.swift new file mode 100644 index 0000000..b54d987 --- /dev/null +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCBleRecord.swift @@ -0,0 +1,57 @@ +// +// DCBleRecord.swift +// Example +// +// Created by liangshi on 2025/12/9. +// + +import StarburstSdk + +public class DCBleRecord { + public static let shared = DCBleRecord() + + + public func setup(textCallback:@escaping (String)->Void){ + let asr = StarburstAsrConfig() + asr.isTranslate = true; + asr.fromLanguage = "zh-CN" + asr.toLanguage = "en-US" + asr.isTTs = true + asr.ttsFormat = "mp3" + StarburstSdk.shared().setupDeviceRecord(with: nil, asrConfig: asr) { config in + DCLogger.debug("录音类型 \(config!.type == 0x00 ? "实时录音" : "通话录音")") + } recognizeText: { [weak self] model in + guard let self = self else {return} + guard let model = model else {return} + + if let text = model.textResult{ + DCLogger.debug("识别 = \(text)") + textCallback(text) + } + + } stateChange: { [weak self] code in + guard let self = self else {return} + DCLogger.debug("状态改变 \(code)") + } finished: { filePath in + if let path = filePath,path.count > 0 { + // 文件转存到自己想要保存的位置 + DCLogger.debug("文件录音保存路径 \(path)") + } + else{ + DCLogger.debug("文件录音保存失败") + } + } + } + + + public func startAction(){ + let config = StarburstBleAsrConfig() + config.type = 0x0c/// 0x00实时录音,0x0c通话录音 + //开始录音 + StarburstSdk.shared().startDeviceRecord(config) + + } + public func stopAction(){ + StarburstSdk.shared().stopDeviceRecord() + } +} diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCChat.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCChat.swift new file mode 100644 index 0000000..896baa4 --- /dev/null +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCChat.swift @@ -0,0 +1,79 @@ +// +// DCChat.swift +// Example +// +// Created by liangshi on 2025/12/15. +// + +import StarburstSdk + +public class DCChat{ + public static let shared = DCChat() + var speakerList = [StarbusrtSpeaker]() + public var dialogId = 0 + + public func getVcSpeekerList(finished:@escaping (Any,Bool)->Void){ + StarburstSdk.shared().getVcSpeekerList { [weak self] (list, success) in + guard let self = self else { return } + finished(list,success) + } + } + + public func setup(asrCallback:@escaping (String)->Void,responseCallback:@escaping (String)->Void,dataCallback:@escaping (Int,Data?,Bool)->Void,codeCallback:@escaping (Int)->Void){ + let config = StarburstVoiceChatConfig() + config.tts = true + config.ttsAudioFormat = "mp3" + //以下配置从音色列表获取 + if speakerList.count > 0 { + // config.role = "spongebob" + // config.ttsSpeakerType = "default" + // config.ttsSpeakerId = "BV063_streaming" + config.role = speakerList[0].role + config.ttsSpeakerType = speakerList[0].type + config.ttsSpeakerId = speakerList[0].sid + } + + StarburstSdk.shared().setupVoiceChat(with: config) { dialogId in + print("开始对话 = \(dialogId)") + } textCallback: {[weak self] model in + guard let model = model else { return } + self?.dialogId = model.dialogId + + if let textResult = model.textResult,textResult.count > 0 { + let text = "[send]" + model.textResult + "\n" + DCLogger.debug(text) + asrCallback(model.textResult) + } else if model.conversationFinish == true && model.responseText != nil + && model.responseText!.count > 0 + { + let text = "[send]" + model.responseText + "\n" + DCLogger.debug(text) + responseCallback(model.responseText) + } else { + return + } + + } responseVoice: { [weak self] (dialogId,data, finish) in + guard let self = self else { return } + self.dialogId = dialogId + dataCallback(dialogId,data,finish) + } stateChange: {code in + DCLogger.debug("状态改变 \(code)") + codeCallback(code.rawValue) + } finished: { filePath in + DCLogger.debug("结束对话") + } + } + public func startChat(){ + + } + public func stopChat(){ + StarburstSdk.shared().stopVoiceChat(self.dialogId) + } + public func startPlayTtsAudio(){ + StarburstSdk.shared().startPlayTtsAudio(self.dialogId) + } + public func stopPlayTtsAudio(){ + StarburstSdk.shared().stopPlayTtsAudio(self.dialogId) + } +} diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCRecord.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCRecord.swift new file mode 100644 index 0000000..868d90b --- /dev/null +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/DeepChordsSdk/DCRecord.swift @@ -0,0 +1,64 @@ +// +// DC.swift +// Example +// +// Created by liangshi on 2025/12/9. +// +import StarburstSdk + +public class DCRecord { + public static let shared = DCRecord() + + public func start(fromLanguage:String,toLanguage:String,textCallback:@escaping (String)->Void){ + let config = StarburstAsrConfig() +// config.isTranslate = true; +// config.fromLanguage = fromLanguage +// config.toLanguage = toLanguage +// config.isTTs = true +// config.ttsFormat = "mp3" + + StarburstSdk.shared().startRecordAsr(config) {voiceData in + //print("录音的音频流 = \(voiceData!)") + } recognizeText: {[weak self] model in + DCLogger.debug(model) + guard let model = model else {return} + if let text = model.textResult ,model.definite{ + DCLogger.debug("确定 text = \(text)") + textCallback(text) + } +// guard let self = self else {return} +// self.resetTimer() +// guard let model = model else {return} +// +// if let translate = model.translateResult,let text = translate.text,translate.definite == true { +// print("确定 text = \(text)") +// self.addText(text) +// } +// if let ttsData = model.ttsResult?.streamPiece { +// //收到的tts +// if self.ttsData == nil{ +// self.ttsData = Data() +// } +// if let data = Data(base64Encoded: ttsData){ +// self.ttsData?.append(data) +// } +// } + } stateChange: {[weak self] code in + DCLogger.debug("状态改变",code) +// guard let self = self else {return} +// if code == .unAuth{ +// self.view.makeToast("未鉴权") +// self.recordBtn.isSelected = false +// } + } interruption: { [weak self] in +// self?.stopAction() + + } + } + public func stop(){ + StarburstSdk.shared().stopRecordAsr {filePath in + DCLogger.debug("文件录音保存路径 \(filePath)") + } + + } +} diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example.xcodeproj/project.pbxproj b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example.xcodeproj/project.pbxproj index 5055fcd..3e37ec9 100644 --- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example.xcodeproj/project.pbxproj +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example.xcodeproj/project.pbxproj @@ -240,6 +240,7 @@ TargetAttributes = { 3F3F01E22ED451920038A1C8 = { CreatedOnToolsVersion = 16.4; + LastSwiftMigration = 1640; }; 3F3F13E22ED5A8C10038A1C8 = { CreatedOnToolsVersion = 16.4; @@ -375,6 +376,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = G23X75CJ67; @@ -437,6 +439,8 @@ PRODUCT_BUNDLE_IDENTIFIER = deepchords.guchuandao.Example; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "Example/VC/Example-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -448,6 +452,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = G23X75CJ67; @@ -510,6 +515,7 @@ PRODUCT_BUNDLE_IDENTIFIER = deepchords.guchuandao.Example; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "Example/VC/Example-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/Info.plist b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/Info.plist index 87b8afa..b571c8d 100644 --- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/Info.plist +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/Info.plist @@ -28,5 +28,7 @@ CFBundleDisplayName 骨传导sdk + NSMicrophoneUsageDescription + 使用麦克风哦 diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/BaseVC.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/BaseVC.swift index ec48eee..e37c695 100644 --- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/BaseVC.swift +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/BaseVC.swift @@ -21,7 +21,7 @@ class BaseVC: UIViewController { logBtn.backgroundColor = .blue logBtn.layer.cornerRadius = 30 logBtn.layer.masksToBounds = true - logBtn.setTitle("log1", for: .normal) + logBtn.setTitle("app log", for: .normal) logBtn.addTarget(self, action: #selector(logAction), for: .touchUpInside) self.view.addSubview(logBtn) diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/BleSdkBleChatVC.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/BleSdkBleChatVC.swift new file mode 100644 index 0000000..6aadc88 --- /dev/null +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/BleSdkBleChatVC.swift @@ -0,0 +1,76 @@ +// +// Untitled.swift +// Example +// +// Created by liangshi on 2025/12/15. +// + +import UIKit +import DeepChordsSdk +import AVFoundation +class BleSdkBleChatVC: BaseVC { + var recordBtn = UIButton(type: .custom) + private var textView = UITextView() + + + deinit { + stopAction() + } + + override func viewDidLoad() { + super.viewDidLoad() + setupViews() + setupSDk() + } + + func setupViews() { + self.title = "耳机对话" + + textView.isEditable = false + self.view.addSubview(textView) + textView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + + recordBtn.backgroundColor = .blue + recordBtn.setTitle("stop", for: .normal) + recordBtn.setTitle("stop", for: .selected) + recordBtn.addTarget(self, action: #selector(recordAction), for: .touchUpInside) + recordBtn.frame = CGRectMake(0, 0, 80, 40) + self.navigationItem.rightBarButtonItems = [UIBarButtonItem(customView: recordBtn)] + } + func setupSDk(){ + ChatManager.shared.asrCallBack = {[weak self] text in + guard let self = self else{return} + let text = "[sebd]" + text + "\n\n" + self.textView.text = self.textView.text + text + let range = NSRange( + location: self.textView.text.count - 1, length: 1) + self.textView.scrollRangeToVisible(range) + } + ChatManager.shared.reponseCallBack = {[weak self] text in + guard let self = self else{return} + let text = "[recieve]" + text + "\n\n" + self.textView.text = self.textView.text + text + let range = NSRange( + location: self.textView.text.count - 1, length: 1) + self.textView.scrollRangeToVisible(range) + } + } + @objc func recordAction() { +// self.recordBtn.isSelected = !self.recordBtn.isSelected +// if self.recordBtn.isSelected { +// DCChat.shared.startChat() +// } +// else{ + stopAction() +// } + } + func stopAction() { + DCChat.shared.stopChat() + } + + + +} + diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/BleSdkEarPhonesAsrVC.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/BleSdkEarPhonesAsrVC.swift new file mode 100644 index 0000000..162cb9c --- /dev/null +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/BleSdkEarPhonesAsrVC.swift @@ -0,0 +1,84 @@ +// +// Untitled.swift +// Example +// +// Created by liangshi on 2025/12/9. +// + +import UIKit +import DeepChordsSdk +class BleSdkEarPhonesAsrVC: BaseVC { + var textView = UITextView() + var recordBtn = UIButton(type: .custom) + var preText = "" + + override func viewDidLoad() { + super.viewDidLoad() + setupViews() + setupSdk() + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + stopAction() + } + + func setupViews(){ + title = "耳机录音" + view.backgroundColor = .white + + recordBtn.backgroundColor = .blue + recordBtn.setTitle("start", for: .normal) + recordBtn.setTitle("stop", for: .selected) + recordBtn.addTarget(self, action: #selector(recordAction), for: .touchUpInside) + recordBtn.frame = CGRectMake(0, 0, 80, 40) + self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: recordBtn) + + textView.isEditable = false + view.addSubview(textView) + textView.frame = CGRectMake(0, 100, view.bounds.size.width, view.bounds.size.height - 100) + } + func setupSdk(){ + //设置回调 + DCBleRecord.shared.setup {[weak self] text in + guard let self = self else{return} + + self.textView.text += text + let range = NSMakeRange(textView.text.count - 1, 1) + self.textView.scrollRangeToVisible(range) + } + } + + @objc func recordAction() { + self.recordBtn.isSelected = !self.recordBtn.isSelected + if self.recordBtn.isSelected { + startAction() + } + else{ + stopAction() + } + } +} +extension BleSdkEarPhonesAsrVC{ + func startAction(){ + DCBleRecord.shared.startAction() + + } + func stopAction(){ + DCBleRecord.shared.stopAction() + } +} + +extension BleSdkEarPhonesAsrVC{ + func addText(_ text:String){ + self.textView.text += text + let range = NSMakeRange(textView.text.count - 1, 1) + self.textView.scrollRangeToVisible(range) + } + func removePreText(){ + if self.textView.text.count - self.preText.count > 0{ + self.textView.text = String(self.textView.text.prefix(self.textView.text.count - self.preText.count)) + self.preText = "" + } + } +} diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/BleSdkPhoneAsrVC.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/BleSdkPhoneAsrVC.swift new file mode 100644 index 0000000..de577c7 --- /dev/null +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/BleSdkPhoneAsrVC.swift @@ -0,0 +1,173 @@ +// +// Ble.swift +// Example +// +// Created by liangshi on 2025/12/9. +// + +import UIKit +import DeepChordsSdk + +class BleSdkPhoneAsrVC: BaseVC { + var textView = UITextView() + var recordBtn = UIButton(type: .custom) + var preText = "" + var ttsData:Data? + var timer: Timer? + + var fromLanguage = "zh-CN" + var toLanguage = "en-US" + var fromItem:UIBarButtonItem! + var toItem:UIBarButtonItem! + + override func viewDidLoad() { + super.viewDidLoad() + title = "手机录音" + view.backgroundColor = .white + +// fromItem = UIBarButtonItem(title: "源语言", style: .done, target: self, action: #selector(fromLanguageAction)) +// toItem = UIBarButtonItem(title: "目标语言", style: .done, target: self, action: #selector(toLanguageAction)) +// self.navigationItem.rightBarButtonItems = [ +// fromItem,toItem +// ]; +// + recordBtn.backgroundColor = .blue + recordBtn.setTitle("开始录音", for: .normal) + recordBtn.setTitle("停止录音", for: .selected) + recordBtn.addTarget(self, action: #selector(recordAction), for: .touchUpInside) + view.addSubview(recordBtn) + recordBtn.snp.makeConstraints { make in + make.width.centerX.bottom.equalToSuperview() + make.height.equalTo(80) + } + + textView.isEditable = false + view.addSubview(textView) + textView.snp.makeConstraints { make in + make.width.centerX.equalToSuperview() + make.top.equalToSuperview().inset(120) + make.bottom.equalTo(recordBtn.snp.top) + } + } + + + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + stopAction() + } + + func setupSdk(){ + + } + + @objc func fromLanguageAction(){ + let vc = SelectLanuageVC() + vc.didSelectedCallback = { (name,value) in + self.fromLanguage = value + self.fromItem.title = name + } + navigationController?.pushViewController(vc, animated: true) + } + @objc func toLanguageAction(){ + let vc = SelectLanuageVC() + vc.didSelectedCallback = { (name,value) in + self.toLanguage = value + self.toItem.title = name + } + navigationController?.pushViewController(vc, animated: true) + } + + @objc func recordAction() { + self.recordBtn.isSelected = !self.recordBtn.isSelected + if self.recordBtn.isSelected { + startAction() + } + else{ + stopAction() + } + } +} + +extension BleSdkPhoneAsrVC{ + func startAction(){ + DCRecord.shared.start(fromLanguage: fromLanguage, toLanguage: toLanguage, textCallback: { [weak self] text in + guard let self = self else{return} + + self.textView.text += text + let range = NSMakeRange(textView.text.count - 1, 1) + self.textView.scrollRangeToVisible(range) + }) + } + + func stopAction(){ +// StarburstSdk.shared().stopRecordAsr {filePath in +// if let path = filePath,path.count > 0 { +// // 文件转存到自己想要保存的位置 +// print("文件录音保存路径 \(path)") +// } +// else{ +// print("文件录音保存失败") +// } +// } +// self.invalidateTimer() + DCRecord.shared.stop() + } + + func resetTimer() { + self.invalidateTimer() + self.timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(timerFired), userInfo: nil, repeats: false) + } + + func invalidateTimer() { + self.timer?.invalidate() + self.timer = nil + } + + @objc func timerFired() { + if let data = self.ttsData { + self.saveToFile(data: data) + self.ttsData = nil + } + } +} + +extension BleSdkPhoneAsrVC{ + func addText(_ text:String){ + self.textView.text += text + let range = NSMakeRange(textView.text.count - 1, 1) + self.textView.scrollRangeToVisible(range) + } + func saveToFile(data: Data) { + let format = DateFormatter() + format.dateFormat = "yyyyMMddHHmmss" + let time = format.string(from: Date()) + +// let filePath = NSHomeDirectory() + "/Documents/\(time).mp3" +// let url = URL(fileURLWithPath: filePath) +// do { +// try data.write(to: url) +// print("\(filePath)") +// PlayerManager.shared.play(filePath: filePath,dialoIg: 0) { (success,dialoIg) in +// print("播放结束 = \(success)") +// } +// // saveFile(withFilePath: filePath) +// } catch let error { +// print("\(error)") +// } + } + + func saveFile(withFilePath filePath: String) { + let fUrl = URL(fileURLWithPath: filePath) + let vc = UIDocumentPickerViewController(url: fUrl, in:.exportToService) + vc.delegate = self + vc.modalPresentationStyle = .overFullScreen + self.present(vc, animated: true, completion: nil) + } +} + +extension BleSdkPhoneAsrVC:UIDocumentPickerDelegate{ + func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { + controller.dismiss(animated: true, completion: nil) + } +} diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/ChatManager.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/ChatManager.swift new file mode 100644 index 0000000..0359daf --- /dev/null +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/ChatManager.swift @@ -0,0 +1,112 @@ +// +// ChatManager.swift +// Example +// +// Created by liangshi on 2025/12/15. +// +import AVFoundation +import DeepChordsSdk + +class ChatManager:NSObject{ + static let shared = ChatManager() + var isTtsPlaying = false + + private var audioData: Data? + + var asrCallBack:((String)->Void)? + var reponseCallBack:((String)->Void)? + + func setupSdk(){ + + 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 { + DCLogger.debug(error) + } + + setupChat() + } + + func setupChat(){ + DCChat.shared.getVcSpeekerList { list, success in + + } + DCChat.shared.setup { text in + self.asrCallBack?(text) + } responseCallback: { text in + self.reponseCallBack?(text) + } dataCallback: {[weak self] dialogId, data, finish in + guard let self = self else { return } +// PcmSound.sharedInstance().delegate = self +// if (!isTtsPlaying) { +// isTtsPlaying = true +// DCLogger.debug("开始播放") +// DCChat.shared.startPlayTtsAudio() +// } +// DCLogger.debug("收到音频数据", data?.count ?? 0) +// PcmSound.sharedInstance().feed(data) + + if finish { + self.saveToFile(data: self.audioData!) + self.audioData = nil + } else { + if self.audioData == nil { + self.audioData = Data() + } + self.audioData?.append(data!) + } + }codeCallback: { code in +// 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) +// } +// } +// } + } + } + + 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 ChatManager : PcmSoundDelegate { + func remaining(_ frames: UInt) { + DCLogger.debug("[frame:\(frames)]"); + if (frames == 0) { + DCChat.shared.stopPlayTtsAudio() + } + } +} diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/Demo.h b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/Demo.h new file mode 100644 index 0000000..00760aa --- /dev/null +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/Demo.h @@ -0,0 +1,16 @@ +// +// Demo.h +// Example +// +// Created by liangshi on 2025/12/15. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface Demo : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/Demo.m b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/Demo.m new file mode 100644 index 0000000..9d53b65 --- /dev/null +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/Demo.m @@ -0,0 +1,12 @@ +// +// Demo.m +// Example +// +// Created by liangshi on 2025/12/15. +// + +#import "Demo.h" + +@implementation Demo + +@end diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/DeviceListVC.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/DeviceListVC.swift index 8cc78b1..34efe20 100644 --- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/DeviceListVC.swift +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/DeviceListVC.swift @@ -8,6 +8,7 @@ import UIKit import SnapKit import CoreBluetooth +import DeepChordsSdk class DeviceListVC: BaseVC{ let tableView = UITableView(frame: .zero, style: .plain) var list:[CBPeripheral] = [ ] @@ -18,6 +19,7 @@ class DeviceListVC: BaseVC{ setupViews() setupBle() + setupSdk() } func setupViews(){ @@ -39,6 +41,20 @@ class DeviceListVC: BaseVC{ self?.navigationController?.popViewController(animated: true) } } + func setupSdk(){ + DeepChordsAiSdk.shared.authCallback = { [weak self] (code,string) in + DCLogger.debug("鉴权结果",code,string) + App.shared.window?.hideToastActivity() + if code == 200{ + + App.shared.window?.makeToast("鉴权成功") + App.shared.window?.rootViewController = UINavigationController(rootViewController: HomeVC()) + } + else{ + App.shared.window?.makeToast(string) + } + } + } } extension DeviceListVC:UITableViewDelegate,UITableViewDataSource { @@ -56,8 +72,9 @@ extension DeviceListVC:UITableViewDelegate,UITableViewDataSource { return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + App.shared.window?.makeToastActivity(.center) let data = list[indexPath.row] - didSelectedCallback?(data) - BleManager.shared.stopScanDevice() + BleManager.shared.connectPeripheral(data) +// App.shared.window?.rootViewController = UINavigationController(rootViewController: HomeVC()) } } diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/Example-Bridging-Header.h b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/Example-Bridging-Header.h new file mode 100644 index 0000000..2ffc88b --- /dev/null +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/Example-Bridging-Header.h @@ -0,0 +1,5 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#import "PcmSound.h" diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/HomeVC.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/HomeVC.swift index 6daa043..e4ac6bc 100644 --- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/HomeVC.swift +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/HomeVC.swift @@ -15,6 +15,9 @@ class HomeVC: BaseVC{ ("获取电量","batteryAction"), ("获取软件版本","softVersionAction"), ("获取硬件版本","hardVersionAction"), + ("现场录音","recordAction"), + ("耳机录音","bleAsrAction"), + ("对话","chatAction"), ] override func viewDidLoad() { @@ -22,15 +25,19 @@ class HomeVC: BaseVC{ // Do any additional setup after loading the view. setupViews() - setupSdk() setupBle() + + DispatchQueue.main.asyncAfter(deadline:.now() + 2) { + ChatManager.shared.setupSdk() + } + } func setupViews(){ self.title = "设备鉴权+设备采集音频" - self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "扫描", style: .done, target: self, action: #selector(scanAction)) +// self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "扫描", style: .done, target: self, action: #selector(scanAction)) - let tableView = UITableView(frame: CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height), style: .plain) + let tableView = UITableView(frame: CGRectMake(0, 80, self.view.bounds.size.width, self.view.bounds.size.height), style: .plain) tableView.delegate = self tableView.dataSource = self tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") @@ -84,21 +91,19 @@ extension HomeVC{ } } } + + @objc func recordAction(){ + self.navigationController?.pushViewController(BleSdkPhoneAsrVC(), animated: true) + } + @objc func bleAsrAction(){ + navigationController?.pushViewController(BleSdkEarPhonesAsrVC(), animated: true) + } + @objc func chatAction(){ + navigationController?.pushViewController(BleSdkBleChatVC(), animated: true) + } } extension HomeVC{ - func setupSdk(){ - DeepChordsAiSdk.shared.authCallback = { [weak self] (code,string) in - DCLogger.debug("鉴权结果",code,string) - if code == 200{ - - App.shared.window?.makeToast("鉴权成功") - } - else{ - App.shared.window?.makeToast(string) - } - } - } func setupBle(){ let shared = BleManager.shared shared.autoConnect() @@ -110,13 +115,14 @@ extension HomeVC{ //蓝牙已经断开 } } + - @objc func scanAction(){ - let scanVC = DeviceListVC() - navigationController?.pushViewController(scanVC, animated: true) - scanVC.list = BleManager.shared.devices - scanVC.didSelectedCallback = { device in - BleManager.shared.connectPeripheral(device) - } - } +// @objc func scanAction(){ +// let scanVC = DeviceListVC() +// navigationController?.pushViewController(scanVC, animated: true) +// scanVC.list = BleManager.shared.devices +// scanVC.didSelectedCallback = { device in +// BleManager.shared.connectPeripheral(device) +// } +// } } diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/LogVC.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/LogVC.swift index ede1643..7b687b6 100644 --- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/LogVC.swift +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/LogVC.swift @@ -22,8 +22,9 @@ class LogVC: UIViewController { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) - - textView.text = DCLogger.logs.joined() +// var version = (Bundle.main.appVersion ?? "") + "\n" + let version = "2025151001" + "\n" + textView.text = "版本:\(version)" + DCLogger.logs.joined() let range = NSMakeRange(textView.text.count - 1, 1) textView.scrollRangeToVisible(range) } @@ -38,7 +39,7 @@ class LogVC: UIViewController { return } // 构建压缩文件路径 - let filePath = cacheDirectory.appendingPathComponent("DeepChordsSdk_\(name).txt").path + let filePath = cacheDirectory.appendingPathComponent("DeepChords_\(name).txt").path let url = URL(fileURLWithPath: filePath) let data = self.textView.text.data(using:.utf8) @@ -69,3 +70,12 @@ extension LogVC:UIDocumentPickerDelegate{ controller.dismiss(animated: true, completion: nil) } } +extension Bundle { + var appVersion: String? { + return infoDictionary?["CFBundleShortVersionString"] as? String + } + + var appBuild: String? { + return infoDictionary?["CFBundleVersion"] as? String + } +} diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/PcmSound.h b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/PcmSound.h new file mode 100644 index 0000000..b599bea --- /dev/null +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/PcmSound.h @@ -0,0 +1,33 @@ + + +#import + +#define NAMESPACE @"pcm_sound" + +@protocol PcmSoundDelegate + +-(void)remaining:(NSUInteger)frames; + +@end + +@interface PcmSound : NSObject + ++ (PcmSound*)sharedInstance; + +@property(nonatomic,weak) id delegate; + +-(BOOL)isPlaying; + +-(void)setLogLevel:(NSNumber*)logLevelNumber; + +-(void)setup:(int)sampleRate withchannels:(int)numChannels; + +-(void)feed:(NSData*)buffer; + +-(void)setFeedThreshold:(NSNumber*)feedThreshold; + +-(void)stopAudioUnit; + +- (void)cleanup; + +@end diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/PlayerManager.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/PlayerManager.swift new file mode 100644 index 0000000..2e5361d --- /dev/null +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/PlayerManager.swift @@ -0,0 +1,59 @@ +// +// 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) + } +} + + diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/SceneDelegate.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/SceneDelegate.swift index 321585c..4922e1a 100644 --- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/SceneDelegate.swift +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/SceneDelegate.swift @@ -18,7 +18,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). guard let _ = (scene as? UIWindowScene) else { return } App.shared.window = window - window?.rootViewController = UINavigationController(rootViewController: HomeVC()) + window?.rootViewController = UINavigationController(rootViewController: DeviceListVC()) DeepChordsAiSdk.shared.initSDK() } diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/SdkLogVC.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/SdkLogVC.swift index da29f19..373b67b 100644 --- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/SdkLogVC.swift +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/SdkLogVC.swift @@ -33,7 +33,7 @@ class SdkLogVC: UIViewController { formatter.dateFormat = "yyyyMMddHHmmss" let name = formatter.string(from: Date()) - let filePath = "\(NSHomeDirectory())/Documents/DeepChordsSdk_\(name).txt" + let filePath = "\(NSHomeDirectory())/Documents/StarburstSdk_\(name).txt" let url = URL(fileURLWithPath: filePath) let data = self.textView.text.data(using:.utf8) do { @@ -46,15 +46,15 @@ class SdkLogVC: UIViewController { } func saveFile(withFilePath filePath: String) { - let fUrl = URL(fileURLWithPath: filePath) - let vc = UIDocumentPickerViewController(url: fUrl, in:.exportToService) - vc.delegate = self - vc.modalPresentationStyle = .overFullScreen - self.present(vc, animated: true, completion: nil) - -// let vc = UIActivityViewController(activityItems: [URL(fileURLWithPath: filePath)], applicationActivities: nil) +// let fUrl = URL(fileURLWithPath: filePath) +// let vc = UIDocumentPickerViewController(url: fUrl, in:.exportToService) +// vc.delegate = self // vc.modalPresentationStyle = .overFullScreen -// App.shared.topVC().present(vc, animated: true) +// self.present(vc, animated: true, completion: nil) + + let vc = UIActivityViewController(activityItems: [URL(fileURLWithPath: filePath)], applicationActivities: nil) + vc.modalPresentationStyle = .overFullScreen + App.shared.topVC().present(vc, animated: true) } } diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/SelectLanuageVC.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/SelectLanuageVC.swift new file mode 100644 index 0000000..3f821a3 --- /dev/null +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/VC/SelectLanuageVC.swift @@ -0,0 +1,65 @@ +// +// Untitled.swift +// Example +// +// Created by liangshi on 2025/12/9. +// + +import UIKit +import StarburstSdk +import Toast_Swift + +class SelectLanuageVC: BaseVC { + private var tableView: UITableView! + private var list:[(name: String,value:String)] = [ + ("简体中文" ,"zh-CN"), + ("四川话", "sc"), + ("粤语", "cant"), + ("上海话" ,"zh_shanghai"), + ("英文", "en-US"), + ("日语", "ja-JP"), + ("韩语", "ko-KR"), + ("法语", "fr-FR"), + ("西班牙语" ,"es-MX"), + ("葡萄牙语", "pt-BR"), + ("印尼语" ,"id-ID"), + ("俄语","ru-RU"), + ("马来语", "ms-MY"), + ] + var didSelectedCallback: ((String,String) -> Void)? + + override func viewDidLoad() { + super.viewDidLoad() + view.backgroundColor = .white + + tableView = UITableView(frame:.zero, style:.plain) + tableView.dataSource = self + tableView.delegate = self + tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell") + view.addSubview(tableView) + tableView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + } +} +extension SelectLanuageVC:UITableViewDataSource, UITableViewDelegate{ + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return list.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) + let model = list[indexPath.row] + cell.textLabel?.text = model.name + + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + view.makeToastActivity(.center) + let model = list[indexPath.row] + didSelectedCallback?(model.name,model.value) + self.navigationController?.popViewController(animated: true) + + } +} diff --git a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/tools/BleManager.swift b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/tools/BleManager.swift index 508e6c7..0fcd128 100644 --- a/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/tools/BleManager.swift +++ b/DeepChordsSdk_iOS/DeepChordsSdk/Example/Example/tools/BleManager.swift @@ -52,9 +52,9 @@ class BleManager: NSObject { centralManager.connect(peripheral, options: [CBConnectPeripheralOptionNotifyOnConnectionKey: true]) } func autoConnect(){ - if let peripheral = centralManager.retrieveConnectedPeripherals(withServices: [CBUUID(string: "AE30")]).first{ - connectPeripheral(peripheral) - } +// if let peripheral = centralManager.retrieveConnectedPeripherals(withServices: [CBUUID(string: "AE30")]).first{ +// connectPeripheral(peripheral) +// } } } extension BleManager:CBCentralManagerDelegate{ @@ -108,6 +108,7 @@ extension BleManager:CBCentralManagerDelegate{ disConnectDeviceCallback?(peripheral) DCBleManager.shared.centralManager(central, didDisconnectPeripheral: peripheral, error: nil) App.shared.window?.makeToast("蓝牙已断开连接") + App.shared.window?.rootViewController = UINavigationController(rootViewController: DeviceListVC()) } } diff --git a/ShenYin/ShenYin/Api/LogManager.swift b/ShenYin/ShenYin/Api/LogManager.swift index f61e054..8735333 100644 --- a/ShenYin/ShenYin/Api/LogManager.swift +++ b/ShenYin/ShenYin/Api/LogManager.swift @@ -9,7 +9,7 @@ import Foundation /// 日记管理 class Logger { - static var isDebug: Bool = false + static var isDebug: Bool = true fileprivate static let shared = Logger() private var fileHandle:FileHandle?