--- /dev/null
+//
+// 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()
+ }
+}
--- /dev/null
+//
+// 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)
+ }
+}
--- /dev/null
+//
+// 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)")
+ }
+
+ }
+}
TargetAttributes = {
3F3F01E22ED451920038A1C8 = {
CreatedOnToolsVersion = 16.4;
+ LastSwiftMigration = 1640;
};
3F3F13E22ED5A8C10038A1C8 = {
CreatedOnToolsVersion = 16.4;
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;
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";
};
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;
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";
};
</dict>
<key>CFBundleDisplayName</key>
<string>骨传导sdk</string>
+ <key>NSMicrophoneUsageDescription</key>
+ <string>使用麦克风哦</string>
</dict>
</plist>
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)
--- /dev/null
+//
+// 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()
+ }
+
+
+
+}
+
--- /dev/null
+//
+// 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 = ""
+ }
+ }
+}
--- /dev/null
+//
+// 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)
+ }
+}
--- /dev/null
+//
+// 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()
+ }
+ }
+}
--- /dev/null
+//
+// Demo.h
+// Example
+//
+// Created by liangshi on 2025/12/15.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface Demo : NSObject
+
+@end
+
+NS_ASSUME_NONNULL_END
--- /dev/null
+//
+// Demo.m
+// Example
+//
+// Created by liangshi on 2025/12/15.
+//
+
+#import "Demo.h"
+
+@implementation Demo
+
+@end
import UIKit
import SnapKit
import CoreBluetooth
+import DeepChordsSdk
class DeviceListVC: BaseVC{
let tableView = UITableView(frame: .zero, style: .plain)
var list:[CBPeripheral] = [ ]
setupViews()
setupBle()
+ setupSdk()
}
func setupViews(){
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 {
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())
}
}
--- /dev/null
+//
+// Use this file to import your target's public headers that you would like to expose to Swift.
+//
+
+#import "PcmSound.h"
("获取电量","batteryAction"),
("获取软件版本","softVersionAction"),
("获取硬件版本","hardVersionAction"),
+ ("现场录音","recordAction"),
+ ("耳机录音","bleAsrAction"),
+ ("对话","chatAction"),
]
override func viewDidLoad() {
// 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")
}
}
}
+
+ @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()
//蓝牙已经断开
}
}
+
- @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)
+// }
+// }
}
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)
}
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)
controller.dismiss(animated: true, completion: nil)
}
}
+extension Bundle {
+ var appVersion: String? {
+ return infoDictionary?["CFBundleShortVersionString"] as? String
+ }
+
+ var appBuild: String? {
+ return infoDictionary?["CFBundleVersion"] as? String
+ }
+}
--- /dev/null
+
+
+#import <Foundation/Foundation.h>
+
+#define NAMESPACE @"pcm_sound"
+
+@protocol PcmSoundDelegate <NSObject>
+
+-(void)remaining:(NSUInteger)frames;
+
+@end
+
+@interface PcmSound : NSObject
+
++ (PcmSound*)sharedInstance;
+
+@property(nonatomic,weak) id<PcmSoundDelegate> 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
--- /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)
+ }
+}
+
+
// 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()
}
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 {
}
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)
}
}
--- /dev/null
+//
+// 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)
+
+ }
+}
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{
disConnectDeviceCallback?(peripheral)
DCBleManager.shared.centralManager(central, didDisconnectPeripheral: peripheral, error: nil)
App.shared.window?.makeToast("蓝牙已断开连接")
+ App.shared.window?.rootViewController = UINavigationController(rootViewController: DeviceListVC())
}
}
/// 日记管理
class Logger {
- static var isDebug: Bool = false
+ static var isDebug: Bool = true
fileprivate static let shared = Logger()
private var fileHandle:FileHandle?