From: liangzhenying <867174124@qq.com> Date: Thu, 22 Aug 2024 07:17:37 +0000 (+0800) Subject: 泰凌微调试 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=44447be6cbec40b7eb16aaa044b608ad6924cb94;p=mirrors%2FMouseSdk-TLW.git 泰凌微调试 --- diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/ADPCMConverter.h b/MouseSdk/AiMouseSdk/TlwMouseSdk/ADPCMConverter.h new file mode 100644 index 0000000..0558f1e --- /dev/null +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/ADPCMConverter.h @@ -0,0 +1,18 @@ +// +// AiAdpcm2pcm.h +// AiMouseSdk +// +// Created by incar on 2024/8/20. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ADPCMConverter : NSObject + +- (NSData *)convertADPCMToPCM:(NSData *)adpcmData; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/ADPCMConverter.m b/MouseSdk/AiMouseSdk/TlwMouseSdk/ADPCMConverter.m new file mode 100644 index 0000000..42e25f3 --- /dev/null +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/ADPCMConverter.m @@ -0,0 +1,92 @@ + +#import "ADPCMConverter.h" +#import + + + +@implementation ADPCMConverter + +static const signed char idxtbl[] = { -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8}; +static const unsigned short steptbl[] = { + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 +}; + +#define NUM_OF_ORIG_SAMPLE 2 + +- (NSData *)convertADPCMToPCM:(NSData *)adpcmData { + NSMutableData *pcmData = [NSMutableData data]; + const signed short *source = (const signed short *)[adpcmData bytes]; + signed short *destination = (signed short *)[pcmData mutableBytes]; + int len = (int)[adpcmData length] / sizeof(signed short); + + int i; + // 假设 source 中的前两个元素分别是 predict 和 predict_idx + int predict = source[0]; + int predict_idx = source[1] & 0xff; + const unsigned char *pcode = (const unsigned char *)(source + NUM_OF_ORIG_SAMPLE); + unsigned char code; + code = *pcode++; + + for (i = 0; i < len; i++) { + if (1) { + int step = steptbl[predict_idx]; + + int diffq = step >> 3; + + if (code & 4) { + diffq = diffq + step; + } + step = step >> 1; + if (code & 2) { + diffq = diffq + step; + } + step = step >> 1; + if (code & 1) { + diffq = diffq + step; + } + + if (code & 8) { + predict = predict - diffq; + } else { + predict = predict + diffq; + } + + if (predict > 32767) { + predict = 32767; + } else if (predict < -32768) { + predict = -32768; + } + + predict_idx = predict_idx + idxtbl[code & 15]; + + if (predict_idx < 0) { + predict_idx = 0; + } else if (predict_idx > 88) { + predict_idx = 88; + } + + if (i & 1) { + code = *pcode++; + } else { + code = code >> 4; + } + } + + if (0 && i < NUM_OF_ORIG_SAMPLE) { + destination[i] = source[i]; + } else { + destination[i] = predict; + } + } + return pcmData; +} + +@end diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/Aiaa.h b/MouseSdk/AiMouseSdk/TlwMouseSdk/Aiaa.h new file mode 100644 index 0000000..f31d545 --- /dev/null +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/Aiaa.h @@ -0,0 +1,21 @@ +// +// Aiaa.h +// AiMouseSdk +// +// Created by incar on 2024/4/27. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface AiTrippleModel : NSObject +@property (nonatomic,strong) NSString *productKey;//产品秘钥 +@property (nonatomic,strong) NSString *deviceName;//设备名称 +@property (nonatomic,strong) NSString *timeStamp;//时间戳 +@property (nonatomic,strong) NSString *signmethod;//签名方法 +@property (nonatomic,strong) NSString *sign; //签名 +@property (nonatomic,strong) NSString *sonce;//用于签名的随机盐值 +@end + +NS_ASSUME_NONNULL_END diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwAudioManager.h b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwAudioManager.h new file mode 100644 index 0000000..bcbc620 --- /dev/null +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwAudioManager.h @@ -0,0 +1,20 @@ +// +// TlwAudioManager.h +// AiMouse +// +// Created by incar on 2024/2/28. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface TlwAudioManager : NSObject +@property (nonatomic,strong)void (^outputData)(NSData *data); +@property (nonatomic,strong)void (^decodeCallBack)(NSData *data); +@property (nonatomic,strong)void (^outputLog)(NSString *log); + +- (void)receiveData:(NSData *)data; +@end + +NS_ASSUME_NONNULL_END diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwAudioManager.m b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwAudioManager.m new file mode 100644 index 0000000..460f163 --- /dev/null +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwAudioManager.m @@ -0,0 +1,50 @@ +// +// TlwAudioManager.m +// AiMouse +// +// Created by incar on 2024/2/28. +// + +#import "TlwAudioManager.h" +#import +#import "ADPCMConverter.h" +#import "adpcm.h" + +@interface TlwAudioManager () +@end + +@implementation TlwAudioManager + +-(instancetype)init{ + if (self = [super init]) { + + } + return self; +} + +- (void)receiveData:(NSData *)data{ +// [self.audioDecoder decodeSBCData:data]; + + NSData *pcmData = [self convertADPCMDataToPCMData:data]; + if(self.decodeCallBack)self.decodeCallBack(pcmData); +} +- (NSData *)convertADPCMDataToPCMData:(NSData *)adpcmData { + const unsigned char *adpcmBytes = (const unsigned char *)[adpcmData bytes]; + NSUInteger adpcmLength = [adpcmData length]; + + signed short *ps = (signed short *)malloc(adpcmLength); + memcpy(ps, adpcmBytes, adpcmLength); + + signed short *pd = (signed short *)malloc(adpcmLength * 4); + + adpcm_to_pcm(ps, pd, adpcmLength / sizeof(signed short)*2); + + NSData *pcmData = [NSData dataWithBytes:pd length:adpcmLength * 4]; + + free(ps); + free(pd); + + return pcmData; +} + +@end diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwConnectManager.h b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwConnectManager.h new file mode 100644 index 0000000..8a76ef8 --- /dev/null +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwConnectManager.h @@ -0,0 +1,35 @@ +// +// TlwConnectManager.h +// AiMouseSdk +// +// Created by incar on 2024/5/28. +// + +#import + +NS_ASSUME_NONNULL_BEGIN +@class TlwConnectManager; +@protocol TlwConnectManagerDelegate + +- (void)TlwConnectManager:(TlwConnectManager *)manager connectStateDidChange:(BOOL)connected; + +- (void)TlwConnectManagerReSendData:(TlwConnectManager *)manager; + +- (void)TlwConnectManager:(TlwConnectManager *)manager outputLog:(NSString *)log; + +@end +@interface TlwConnectManager : NSObject +@property (nonatomic, weak) id delegate; + +- (void)start; + +//重置 +- (void)resetTimeOut; + +/// 增加超时 +- (void)addTimeOut; + +- (void)disConnected; +@end + +NS_ASSUME_NONNULL_END diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwConnectManager.m b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwConnectManager.m new file mode 100644 index 0000000..e81e7ce --- /dev/null +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwConnectManager.m @@ -0,0 +1,94 @@ +// +// TlwConnectManager.m +// AiMouseSdk +// +// Created by incar on 2024/5/28. +// + +#import "TlwConnectManager.h" + +@interface TlwConnectManager() +@property (nonatomic, assign) NSInteger currentValue;//当前计数 +@property (nonatomic, assign) NSInteger timeOut;//超时次数 +@property (nonatomic, strong) NSTimer *timer; +@property (nonatomic, assign) int connecteState;//连接状态0未知,1连上,2断开连接 +@end + +@implementation TlwConnectManager +-(instancetype)init{ + if (self = [super init]) { + + } + return self; +} + +- (void)start{ + self.timeOut = 0; + self.connecteState = 0; + + [self addSendTimer]; +} + +- (void)resetTimeOut{ + self.timeOut = 0; + self.currentValue = 0; + + if (self.connecteState != 1) { + [self showLog:@"连上设备。。。"]; + [self.delegate TlwConnectManager:self connectStateDidChange:true]; + } + self.connecteState = 1; +} + +- (void)addTimeOut{ + self.timeOut++; + + if (self.timeOut >= 3) { + if (self.connecteState != 2) { + [self showLog:@"设备断开连接!!!"]; + [self.delegate TlwConnectManager:self connectStateDidChange:false]; + } + self.connecteState = 2; + } +} + +- (void)disConnected{ + [self showLog:@"设备断开连接!!!"]; + [self.delegate TlwConnectManager:self connectStateDidChange:false]; + self.connecteState = 2; +} +#pragma mark - timer +- (void)addSendTimer{ + dispatch_async(dispatch_queue_create("timeoutQueue", DISPATCH_QUEUE_SERIAL), ^{ + self.timer = [NSTimer timerWithTimeInterval:1000 target:self selector:@selector(timerAction) userInfo:nil repeats:true]; + [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes]; + [[NSRunLoop currentRunLoop] run]; + }); +// self.timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(timerAction) userInfo:nil repeats:true]; +// [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes]; +} + +//- (void)removeSendTimer{ +// if (self.timer && [self.timer isValid]) { +// [self.timer invalidate]; +// } +//} + +- (void)timerAction{ + self.currentValue++; +// [self showLog:[NSString stringWithFormat:@"time = %ld",self.currentValue]]; + if (self.currentValue >= 3) { + self.currentValue = 0; + if (self.delegate && [self.delegate respondsToSelector:@selector(TlwConnectManagerReSendData:)]) { +// [self showLog:@"检查是否断开连接"]; + [self.delegate TlwConnectManagerReSendData:self]; + } + } +} + +- (void)showLog:(NSString *)log{ + if (self.delegate && [self.delegate respondsToSelector:@selector(TlwConnectManager:outputLog:)]) { + [self.delegate TlwConnectManager:self outputLog:log]; + } +} +@end diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.h b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.h new file mode 100644 index 0000000..98376d5 --- /dev/null +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.h @@ -0,0 +1,102 @@ +// +// AiMouseSdk.h +// AiMouseSdk +// +// Created by incar on 2024/4/23. +// + +#import + +@interface TlwDeviceInfo : NSObject +@property (nonatomic, assign) int DPI;/// DPI值 数值1 ~ 4 (分别对应 800 1200 1800 2400) +@property (nonatomic, assign) int version;///软件版本 +@property (nonatomic, assign) int batteryState;/// 电池状态 +@property (nonatomic, assign) int batteryValue;/// 电池百分百电量,0-100 +@end + +/// 日志等级 +typedef NS_ENUM(NSInteger,TlwMouseLogLevel) { + TlwMouseLogLevel_none = 0, + TlwMouseLogLevel_error, + TlwMouseLogLevel_info, +}; + +typedef NS_ENUM(NSInteger,TlwConnectType) { + TlwConnectType_bluetooth = 0,///蓝牙 + TlwConnectType_hid,///hid +}; + +@protocol TlwMouseDelegate + +/// 设备连接状态 +/// - Parameter connected: 是否连接 +- (void)aiMouseConnectStateDidChange:(BOOL)connected; + +/// 设备信息数据回调,需要将此数据通过设备信息特征转发给蓝牙设备 +/// - Parameter data: 数据 +- (void)tlwMouseSendDeviceInfoData:(NSData *)data; + +/// 鼠标按键指令回调 +/// - Parameter data: 数据。 +/// 前 单击0x06, 按下0x13(开始录音)抬起0x14(结束录音) +/// 中 单击0x03, 按下0x11(开始录音)抬起0x12(结束录音) +/// 后 第一次单击0x01, 第二次单击0x02(结束录音) , 按下0x09(开始录音)抬起0x10(结束录音) +/// 其他未定义 +- (void)tlwMouseSendCmdData:(NSData *)data; + +/// 录音回调 +/// - Parameter data: pcm格式语音数据 +- (void)tlwMouseSendRecordData:(NSData *)data; + +@optional +/// 输出sdk日志 +/// - Parameter log: 日志 +- (void)aiMouseAddLog:(NSString *)log; + +@end + +@interface TlwMouse : NSObject +@property (nonatomic, weak) id delegate;/// 代理 +@property (nonatomic, readonly) TlwConnectType connectType;//连接类型 +@property (nonatomic, readonly) BOOL connected;//是否已连接 + +/// 单利 ++(TlwMouse *)shared; + +/// 设置日志等级 +/// - Parameter level: 等级 +- (void)setLogLevel:(TlwMouseLogLevel)level; + +/// 断开连接 +- (void)didDisconnect; + +/// 切换连接类型 +/// - Parameter type: 连接类型 +- (void)switchConnect:(TlwConnectType)type; + +/// 传输业务数据给sdk +/// - Parameter data:ai特征传过来的数据 +- (void)sendAiDataToSdk:(NSData *)data; + +/// 传输设备信息数据给sdk +/// - Parameter data:设备信息特征传过来的数据 +- (void)sendDeviceDataToSdk:(NSData *)data; + +/// 获取设备信息 +/// - Parameter completation: 如果获取成功,则deviceInfo有值,否则为nil +- (void)getDeviceInfo:(void (^)(TlwDeviceInfo *deviceInfo,NSError *error))complete; + +/// 设置DPI +/// - Parameters: +/// - value: 数值1 ~ 4 (分别对应 800 1200 1800 2400) +/// - finished: 设置结果回调 +- (void)setDPI:(uint8_t)value completation:(void (^)(BOOL isSuccess,NSError *error))finished; + +/// 打开录音 +/// - finished: 执行结果回调 +- (void)openRecord:(void (^)(BOOL isSuccess,NSError *error))finished; + +/// 关闭录音 +/// - finished: 执行结果回调 +- (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished; +@end diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m new file mode 100644 index 0000000..17654f5 --- /dev/null +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m @@ -0,0 +1,492 @@ +// +// AiMouseSdk.m +// AiMouseSdk +// +// Created by incar on 2024/4/23. +// + +#import "TlwMouseSdk.h" +#import "TlwAudioManager.h" +#import "TlwTools.h" +#import "TlwRecordManager.h" +#import "TlwConnectManager.h" + +@interface TlwDeviceInfo() +@end +@implementation TlwDeviceInfo +-(NSString *)description{ + NSString *info = [NSString stringWithFormat:@"\n version = %d\n DPI = %d\n batteryState = %d\n batteryValue = %d\n",self.version,self.DPI,self.batteryState,self.batteryValue]; + return info; +} +@end + +@interface TlwMouse() + +@property (nonatomic, assign) TlwMouseLogLevel logLevel; +@property (nonatomic, strong) TlwAudioManager *audioManager; +@property (nonatomic, strong) TlwRecordManager *recordManager; +@property (nonatomic, strong) TlwConnectManager *connectManager; + +@property (nonatomic,strong)void (^openRecord)(BOOL isSuccess,NSError *error); +@property (nonatomic,strong)void (^closeRecord)(BOOL isSuccess,NSError *error); +@property (nonatomic,strong)void (^setDpi)(BOOL isSuccess,NSError *error); +@property (nonatomic,strong)void (^getMouseInfo)(TlwDeviceInfo *deviceInfo,NSError *error); +@end + +@implementation TlwMouse ++(TlwMouse *)shared{ + static TlwMouse *manager = nil; + static dispatch_once_t oncePredicate; + dispatch_once(&oncePredicate, ^{ + manager = [[TlwMouse alloc]init]; + }); + return manager; +} + +-(instancetype)init{ + if (self = [super init]) { + _logLevel = TlwMouseLogLevel_none; + _connectType = TlwConnectType_bluetooth; + [self.connectManager start]; + NSLog(@"[AiMouseSdk]%@",[NSString stringWithFormat:@"AiMouseSdk_v%@",self.version]); + } + return self; +} + +-(NSString *)version{ + return @"1.1.0"; +} + +-(TlwAudioManager *)audioManager{ + if (!_audioManager) { + _audioManager = [[TlwAudioManager alloc] init]; + __weak typeof(self) ws = self; + _audioManager.decodeCallBack = ^(NSData * _Nonnull data) { + [ws sendRecordData:data]; + }; + _audioManager.outputLog = ^(NSString * _Nonnull log) { + [ws showLog:log]; + }; + } + return _audioManager; +} + +- (TlwRecordManager *)recordManager{ + if (!_recordManager) { + _recordManager = [[TlwRecordManager alloc] init]; + __weak typeof(self) ws = self; + _recordManager.didRecordData = ^(NSData * _Nonnull data) { + [ws showLog:[NSString stringWithFormat:@"%@",data]]; + [ws sendRecordData:data]; + }; + } + return _recordManager; +} + +-(TlwConnectManager *)connectManager{ + if (!_connectManager) { + _connectManager = [[TlwConnectManager alloc] init]; + _connectManager.delegate = self; + } + return _connectManager; +} + +#pragma mark - pub Api +- (void)setLogLevel:(TlwMouseLogLevel)level{ + _logLevel = level; +} +- (void)didDisconnect{ + [self showLog:@"系统断开连接"]; + [self stopRecord]; + [self.connectManager disConnected]; +} + +- (void)switchConnect:(TlwConnectType)type{ + if(type != _connectType && self.connected){ + [self.connectManager disConnected]; + } + _connectType = type; + [self showLog:type == TlwConnectType_bluetooth?@"sdk切换到蓝牙模式":@"sdk切换到usb模式"]; + + + if (type == TlwConnectType_hid) { + [self.recordManager checkPermissions]; + } +} + +- (void)sendAiDataToSdk:(NSData *)data{ + [self.connectManager resetTimeOut]; + + [self showLog:[NSString stringWithFormat:@"[receive][Ai] %@",data]]; + if(self.connectType == TlwConnectType_hid){ +//// 0AFFFF12BC32 +// if(data.length == 6){ +// NSData *subData = [data subdataWithRange:NSMakeRange(5, 1)]; +// [self sendCmdData:subData]; +// uint8 cmd; +// [subData getBytes:&cmd length:1]; +//// [self showLog:[NSString stringWithFormat:@"cmd = %X",cmdInt]]; +// if(cmd == 0x31 || cmd == 0x21 || cmd == 0x25 ||cmd == 0x27){ +// self.recordManager.startCmd = subData; +// [self startRecord]; +// } +// else if(cmd == 0x32 || cmd == 0x22 || cmd == 0x26 ||cmd == 0x28){ +// [self stopRecord:false]; +// } +// } +// else{ +// [self showLog:@"未实现指令"]; +// } + } + else if (self.connectType == TlwConnectType_bluetooth){ + [self bleReceiveAiData:data]; + } +} + +-(void)sendDeviceDataToSdk:(NSData *)data{ + [self showLog:[NSString stringWithFormat:@"[receive][info] %@",data]]; + if(self.connectType == TlwConnectType_hid){ + [self hidReceiveDeviceData:data]; + } + else if (self.connectType == TlwConnectType_bluetooth){ + [self bleReceiveDeviceData:data]; + } +} +- (void)openRecord:(void (^)(BOOL isSuccess,NSError *error))finished{ + if(self.connectType == TlwConnectType_hid){ + self.openRecord = finished; + uint8_t cmd = 0x03; + uint8_t len = 0x00; + uint8_t tail = 0xEF; + NSMutableData *mData = NSMutableData.data; + [mData appendData:[self getHidHeader]]; + [mData appendBytes:&cmd length:1]; + [mData appendBytes:&len length:1]; + [mData appendBytes:&tail length:1]; + [self sendToDevice:mData]; + } + else if (self.connectType == TlwConnectType_bluetooth){ + self.openRecord = finished; + uint8_t cmd = 0x03; + uint8_t dir = 0x01; + uint8_t len = 0x00; + NSMutableData *mData = NSMutableData.data; + [mData appendBytes:&cmd length:1]; + [mData appendBytes:&dir length:1]; + [mData appendBytes:&len length:1]; + [self sendToDevice:mData]; + } +} +- (void)closeRecord:(void (^)(BOOL isSuccess,NSError *error))finished{ + if(self.connectType == TlwConnectType_hid){ + self.closeRecord = finished; + uint8_t cmd = 0x04; + uint8_t len = 0x00; + uint8_t tail = 0xEF; + NSMutableData *mData = NSMutableData.data; + [mData appendData:[self getHidHeader]]; + [mData appendBytes:&cmd length:1]; + [mData appendBytes:&len length:1]; + [mData appendBytes:&tail length:1]; + [self sendToDevice:mData]; + } + else if (self.connectType == TlwConnectType_bluetooth){ + self.closeRecord = finished; + uint8_t cmd = 0x04; + uint8_t dir = 0x01; + uint8_t len = 0x00; + NSMutableData *mData = NSMutableData.data; + [mData appendBytes:&cmd length:1]; + [mData appendBytes:&dir length:1]; + [mData appendBytes:&len length:1]; + [self sendToDevice:mData]; + } + +} + +- (void)setDPI:(uint8_t)value completation:(void (^)(BOOL isSuccess,NSError *error))finished{ + if(self.connectType == TlwConnectType_hid){ + self.setDpi = finished; + uint8_t type = 0x06; + uint8_t len = 0x01; + uint8_t tail = 0xEF; + NSMutableData *mData = NSMutableData.data; + [mData appendData:[self getHidHeader]]; + [mData appendBytes:&type length:1]; + [mData appendBytes:&len length:1]; + [mData appendBytes:&value length:1]; + [mData appendBytes:&tail length:1]; + [self sendToDevice:mData]; + } + else if (self.connectType == TlwConnectType_bluetooth){ + self.setDpi = finished; + uint8_t cmd = 0x06; + uint8_t dir = 0x01; + uint8_t len = 0x01; + NSMutableData *mData = NSMutableData.data; + [mData appendBytes:&cmd length:1]; + [mData appendBytes:&dir length:1]; + [mData appendBytes:&len length:1]; + [mData appendBytes:&value length:1]; + [self sendToDevice:mData]; + } + + +} +- (void)getDeviceInfo:(void (^)(TlwDeviceInfo *deviceInfo,NSError *error))finished{ + if(self.connectType == TlwConnectType_hid){ + self.getMouseInfo = finished; +// 0x05fff1fec09f0114ef + uint8_t cmd = 0x0c; + uint8_t len = 0x00; + uint8_t tail = 0xEF; + + NSMutableData *mData = NSMutableData.data; + [mData appendData:[self getHidHeader]]; + [mData appendBytes:&cmd length:1]; + [mData appendBytes:&len length:1]; + [mData appendBytes:&tail length:1]; + [self sendToDevice:mData]; + } + else if (self.connectType == TlwConnectType_bluetooth){ + self.getMouseInfo = finished; + uint8_t cmd = 0x0c; + uint8_t dir = 0x01; + uint8_t len = 0x00; + NSMutableData *mData = NSMutableData.data; + [mData appendBytes:&cmd length:1]; + [mData appendBytes:&dir length:1]; + [mData appendBytes:&len length:1]; + [self sendToDevice:mData]; + } +} + +#pragma mark - ble +- (void)bleReceiveAiData:(NSData *)data{ + [self.connectManager resetTimeOut]; + [self.audioManager receiveData:data]; +} + +-(void)bleReceiveDeviceData:(NSData *)data{ + NSData *typeData = [data subdataWithRange:NSMakeRange(0, 1)]; + uint8 type; + [typeData getBytes:&type length:1]; + + NSData *stateData = [data subdataWithRange:NSMakeRange(1, 1)]; + uint8 state; + [stateData getBytes:&state length:1]; + BOOL success = state == 0x02; + + NSData *lenData = [data subdataWithRange:NSMakeRange(2, 1)]; + uint8 len; + [lenData getBytes:&len length:1]; + + switch (type) { + case 0x6A: + //语音开启回复 + [self showLog:[NSString stringWithFormat:@"语音开启回复 %@",@(success)]]; + self.openRecord(success, nil); + break; + case 0x6B: + //语音停止回复 + [self showLog:[NSString stringWithFormat:@"语音停止回复 %@",@(success)]]; + self.closeRecord(success, nil); + break; + case 0x96: + //设置DPI回复 + [self showLog:[NSString stringWithFormat:@"设置DPI回复 %@",@(success)]]; + self.setDpi(success, nil); + break; + case 0x9c: + { //鼠标状态查询回复 + uint16_t version; + [[data subdataWithRange:NSMakeRange(3, 2)] getBytes:&version length:2]; + + uint16_t DPI; + [[data subdataWithRange:NSMakeRange(5, 2)] getBytes:&DPI length:2]; + + uint16_t batteryState; + [[data subdataWithRange:NSMakeRange(7, 1)] getBytes:&batteryState length:1]; + + uint16_t batteryValue; + [[data subdataWithRange:NSMakeRange(8, 1)] getBytes:&batteryValue length:1]; + + TlwDeviceInfo *info = [[TlwDeviceInfo alloc] init]; + info.version = version; + info.DPI = DPI; + info.batteryState = batteryState; + info.batteryValue = batteryValue; + [self showLog:info.description]; + self.getMouseInfo(info, nil); + } + break; + case 0x9f: + { + //鼠标按键上报 + NSData *subData = [data subdataWithRange:NSMakeRange(3, 1)]; + [self sendCmdData:subData]; + } + break; + default: + break; + } +} + +#pragma mark - hid +- (void)hidReceiveDeviceData:(NSData *)data{ +// 0x05fff1fec09f0114ef + uint8 type; + [[data subdataWithRange:NSMakeRange(5, 1)] getBytes:&type length:1]; + + NSData *lenData = [data subdataWithRange:NSMakeRange(6, 1)]; + uint8 len; + [lenData getBytes:&len length:1]; + + switch (type) { + case 0x6A: + { + //语音开启回复 + uint8 state; + [[data subdataWithRange:NSMakeRange(6, 1)] getBytes:&state length:1]; + BOOL success = state == 0x02; + [self showLog:[NSString stringWithFormat:@"语音开启回复 %@",@(success)]]; + self.openRecord(success, nil); + [self startRecord]; + break; + } + + case 0x6B: + { + //语音停止回复 + uint8 state; + [[data subdataWithRange:NSMakeRange(6, 1)] getBytes:&state length:1]; + BOOL success = state == 0x02; + + [self showLog:[NSString stringWithFormat:@"语音停止回复 %@",@(success)]]; + [self stopRecord]; + self.closeRecord(success, nil); + break; + } + case 0x96: + { + //设置DPI回复 + uint8 state; + [[data subdataWithRange:NSMakeRange(6, 1)] getBytes:&state length:1]; + BOOL success = state == 0x02; + + [self showLog:[NSString stringWithFormat:@"设置DPI回复 %@",@(success)]]; + self.setDpi(success, nil); + break; + } + case 0x9c: + { //鼠标状态查询回复 + uint16_t version; + [[data subdataWithRange:NSMakeRange(3, 2)] getBytes:&version length:2]; + + uint16_t DPI; + [[data subdataWithRange:NSMakeRange(5, 2)] getBytes:&DPI length:2]; + + uint16_t batteryState; + [[data subdataWithRange:NSMakeRange(7, 1)] getBytes:&batteryState length:1]; + + uint16_t batteryValue; + [[data subdataWithRange:NSMakeRange(8, 1)] getBytes:&batteryValue length:1]; + + TlwDeviceInfo *info = [[TlwDeviceInfo alloc] init]; + info.version = version; + info.DPI = DPI; + info.batteryState = batteryState; + info.batteryValue = batteryValue; + [self showLog:info.description]; + self.getMouseInfo(info, nil); + } + break; + case 0x9f: + { + NSData *subData = [data subdataWithRange:NSMakeRange(7, 1)]; + [self sendCmdData:subData]; + + uint8 cmd; + [subData getBytes:&cmd length:1]; + + if(cmd == 0x13 || cmd == 0x11 || cmd == 0x01 ||cmd == 0x09){ + self.recordManager.startCmd = subData; + [self startRecord]; + } + else if(cmd == 0x14 || cmd == 0x12 || cmd == 0x02 ||cmd == 0x10){ + [self stopRecord]; + } + } + break; + default: + break; + } +} +- (NSData *)getHidHeader{ + uint8_t head1 = 0x05; + uint16_t head2 = 0xFFF1; + uint8_t head3 = 0xfe; + uint8_t head4 = 0x00; + + NSMutableData *mData = NSMutableData.data; + [mData appendBytes:&head1 length:1]; + [mData appendBytes:&head2 length:2]; + [mData appendBytes:&head3 length:1]; + [mData appendBytes:&head4 length:1]; + + return mData; +} +#pragma mark - other +- (void)sendRecordData:(NSData *)data{ + [self showLog:[NSString stringWithFormat:@"[send][audio] %@",data]]; + if (self.delegate) [self.delegate tlwMouseSendRecordData:data]; +} + +- (void)sendCmdData:(NSData *)data{ + [self showLog:[NSString stringWithFormat:@"[send] %@",data]]; + if (self.delegate) [self.delegate tlwMouseSendCmdData:data]; +} + +- (void)showLog:(NSString *)log{ + if (self.delegate && [self.delegate respondsToSelector:@selector(aiMouseAddLog:)]) { + [self.delegate aiMouseAddLog:[NSString stringWithFormat:@"[AiMouseSdk]%@",log]]; + } + if(self.logLevel == TlwMouseLogLevel_info){ + NSLog(@"[AiMouseSdk]%@",log); + } +} + + +- (void)sendToDevice:(NSData *)data{ + [self showLog:[NSString stringWithFormat:@"[send][info] %@",data]]; + [self.delegate tlwMouseSendDeviceInfoData:data]; +} +#pragma mark - deviceInfo +- (void)startRecord{ + [self.recordManager start]; +} + +- (void)stopRecord{ + if (self.recordManager.recording ) { + [self.recordManager stop]; + } +} + +#pragma mark - TlwConnectManagerDelegate +-(void)TlwConnectManager:(TlwConnectManager *)manager connectStateDidChange:(BOOL)connected{ + _connected = connected; + if([self.delegate respondsToSelector:@selector(aiMouseConnectStateDidChange:)]) [self.delegate aiMouseConnectStateDidChange:connected]; +} +-(void)TlwConnectManagerReSendData:(TlwConnectManager *)manager{ +// __weak typeof(self) ws = self; +// [self.deviceInfoManager getVersion:^(NSString * _Nonnull version, NSError * _Nonnull error) { +// if (error.code == AiMouseErrorCode_timeOut) { +// [ws.connectManager addTimeOut]; +// } +// }]; +} +-(void)TlwConnectManager:(TlwConnectManager *)manager outputLog:(NSString *)log{ + [self showLog:log]; +} +@end + diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwRecordManager.h b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwRecordManager.h new file mode 100644 index 0000000..3d499c6 --- /dev/null +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwRecordManager.h @@ -0,0 +1,25 @@ +// +// TlwRecordManager.h +// AudioRecorder +// +// Created by incar on 2024/3/29. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface TlwRecordManager : NSObject +@property (nonatomic,assign)BOOL recording; +@property (nonatomic,strong)NSData *startCmd; +@property (nonatomic,readonly)NSData *stopCmd; +@property (nonatomic,strong)void (^didRecordData)(NSData *data); + +- (void)checkPermissions; + +- (void)start; + +- (void)stop; +@end + +NS_ASSUME_NONNULL_END diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwRecordManager.m b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwRecordManager.m new file mode 100644 index 0000000..7b3bf47 --- /dev/null +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwRecordManager.m @@ -0,0 +1,194 @@ +// +// TlwRecordManager.m +// AudioRecorder +// +// Created by incar on 2024/3/29. +// + +#import "TlwRecordManager.h" +#import + +@interface TlwRecordManager() +@property (nonatomic,assign)BOOL isAllowRecord; +@property (nonatomic,strong)AVAudioEngine *audioEngine; +@property (nonatomic,strong)AVAudioFile *outputFile; + +@end + +@implementation TlwRecordManager +//+(TlwRecordManager *)shared{ +// static TlwRecordManager *manager = nil; +// static dispatch_once_t oncePredicate; +// dispatch_once(&oncePredicate, ^{ +// manager = [[TlwRecordManager alloc]init]; +// }); +// return manager; +//} + + +-(instancetype)init{ + if (self = [super init ]) { + self.isAllowRecord = false; +// [self checkPermissions]; + } + return self; +} + +- (void)start{ + if (self.isAllowRecord == false) { + return; + } + // let audioSession = AVAudioSession.sharedInstance() + // do { + // try audioSession.setCategory(.playAndRecord, options: .defaultToSpeaker) + // try audioSession.setActive(true, options: .notifyOthersOnDeactivation) + // catch let error as NSError { + // print("ERROR:", error) + // } + self.recording = true; + + self.audioEngine = [[AVAudioEngine alloc] init]; + AVAudioInputNode *input = self.audioEngine.inputNode; + AVAudioNodeBus bus = 0; + AVAudioFormat *inputFormat = [input inputFormatForBus:bus]; + // NSString *fullPath = [NSString stringWithFormat:@"%@1.pcm",NSTemporaryDirectory()]; + // NSURL *fileURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].firstObject URLByAppendingPathComponent:@"record.caf"]; + // [self showLog:fileURL.absoluteString]; + // NSError *err0; + // self.outputFile = [[AVAudioFile alloc] initForWriting:fileURL settings:inputFormat.settings commonFormat:inputFormat.commonFormat interleaved:inputFormat.isInterleaved error:&err0]; + // if (err0) { + // [self showLog:[NSString stringWithFormat:@"设置写入路径 %@", err0.description]]; + // } + // else{ + // [self showLog:@"写入路径设置成功"]; + // } + // self.recordData = [[NSMutableData alloc] init]; + __weak typeof(self) ws = self; + [input installTapOnBus:bus bufferSize:32 format:inputFormat block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) { + NSData *data = [ws pcm_downsample:buffer]; + if (ws.didRecordData) { + ws.didRecordData(data); + } +// NSLog(@"%@",data); +// NSError *err0; + // [ws.outputFile writeFromBuffer:buffer error:&err0]; + // if (err0) { + // [self showLog:[NSString stringWithFormat:@"写入失败 %@", err0.description]]; + // } + // else{ + // [self showLog:@"写入成功"]; + // } + }]; + + NSError *err1; + [self.audioEngine prepare]; + [self.audioEngine startAndReturnError:&err1]; + if (err1) { + [self showLog:[NSString stringWithFormat:@"启动录音失败 %@", err1.description]]; + } + else{ + [self showLog:@"启动成功"]; + } +} + +- (void)stop{ + [self.audioEngine stop]; + self.recording = false; + // [self finishRecored:self.recordData]; +} + +- (void)checkPermissions{ + switch ([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio]) { + case AVAuthorizationStatusAuthorized: + self.isAllowRecord = true; + [self showLog:@"录音已经授权"]; + break; + case AVAuthorizationStatusNotDetermined: + { + [self showLog:@"录音未授权"]; + [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) { + if (granted) { + self.isAllowRecord = true; + [self showLog:@"录音已经授权"]; + } + else{ + [self showLog:@"已拒绝"]; + } + }]; + } + break; + case AVAuthorizationStatusDenied: + [self showLog:@"已拒绝"]; + [self openSettings]; + break; + default: + [self showLog:@"已拒绝"]; + [self openSettings]; + break; + } +} + +- (void)openSettings{ +// NSURL *url = [NSURL URLWithString:@""]; +} + +- (void)showLog:(NSString *)log{ +// NSLog(@"%@",log); +} + +//将录音数据保存 +- (void)finishRecored:(NSData *)data{ + NSString *doc = NSTemporaryDirectory(); + NSString *fullPath = [NSString stringWithFormat:@"%@1.pcm",doc]; + NSError *err; + [data writeToFile:fullPath options:NSDataWritingAtomic error:&err]; + if (err) { + [self showLog:[NSString stringWithFormat:@"录音保存失败 %@",err.description]]; + } + else{ + [self showLog:[NSString stringWithFormat:@"录音保存成功 path = %@",fullPath]]; + } +} + +-(NSData*) pcm_downsample:(AVAudioPCMBuffer*)buffer { + //位深转换 float32 转 int16_t + NSData* pData = [[NSData alloc] initWithBytes:buffer.floatChannelData[0] length:buffer.frameLength * 4]; + Byte*dataByte = (Byte*)[pData bytes]; + NSUInteger srcSize = pData.length/4; + Float32 vf32[srcSize]; + memcpy(vf32, &dataByte[0], pData.length); + int16_t bArr[srcSize]; + int r; + for(size_t i =0; i < srcSize; ++i) { + float x = vf32[i]; + float c; + c = ((x < -1) ? -1: ((x >1) ?1: x)); + c = c +1; + r = (int)(c *32767.5f); + r = r -32768; + bArr[i] = (short)r; + } + //码率转换 44100 转 16000 + uint32_t last_pos = (uint32_t)(srcSize -1); + uint32_t dstSize = (srcSize/44100.0)*16000; + int16_t bArr16[dstSize]; + for(uint32_t idx =0; idx < dstSize; idx++) { + float index = ((float) idx *44100.0) / (16000.0); + uint32_t p1 = (uint32_t) index; + float coef = index - p1; + uint32_t p2 = (p1 == last_pos) ? last_pos : p1 +1; + bArr16[idx] = (int16_t) ((1.0f- coef) * bArr[p1] + coef * bArr[p2]); + } + NSMutableData *data1 = [[NSMutableData alloc] init]; + for(NSUInteger i =0; i < dstSize; i++) { + unsigned char valChar[2]; + valChar[0] =0xff& bArr16[i]; + valChar[1] = (0xff00& bArr16[i]) >>8; + [data1 appendBytes:valChar length:2]; + } + return data1; +} + + + +@end diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwTools.h b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwTools.h new file mode 100644 index 0000000..4eb7bb4 --- /dev/null +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwTools.h @@ -0,0 +1,44 @@ +// +// TlwTools.h +// AiMouse +// +// Created by incar on 2024/2/28. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface TlwTools : NSObject ++ (NSArray *)stringToArray:(NSString *)jsonString; ++ (NSString *)arrayToString:(NSArray *)arr; + ++ (NSDictionary *)stringToDictionary:(NSString *)jsonString; ++ (NSString *)dictionaryToString:(NSDictionary *)dic; + ++ (NSDictionary *)dataToDictionary:(NSData *)jsonData; ++ (NSData *)dictionaryToData:(NSDictionary *)dicJson; + + ++ (NSString *)dataToHexString:(NSData *)data; + ++ (NSString *)dataToHexString_placeholder:(NSData *)data; + ++ (NSData *)hexStringToData:(NSString *)hexStr ; + ++ (NSString *)dataToUtf8String:(NSData *)data; + ++ (NSString *)stringTomd5:(NSString *)str; + ++ (NSString *)stringToHmacSha1:(NSString*)key text:(NSString*)text; + ++ (NSString *)MD5ForUpper32:(NSString *)str; + ++ (NSData *)dataWithHexString:(NSString *)hexStr; + ++(NSString *)randomString:(NSInteger)length; + ++(NSString *)getCurrentTime; +@end + +NS_ASSUME_NONNULL_END diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwTools.m b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwTools.m new file mode 100644 index 0000000..be8f60a --- /dev/null +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/TlwTools.m @@ -0,0 +1,226 @@ +// +// TlwTools.m +// AiMouse +// +// Created by incar on 2024/2/28. +// + +#import "TlwTools.h" +#import +#include +#include + +@implementation TlwTools ++ (NSArray *)stringToArray:(NSString *)jsonString{ + NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; + NSError *error; + NSArray *arr = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; + return arr; +} ++ (NSString *)arrayToString:(NSArray *)arr{ + NSError *error; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:arr options:NSJSONWritingPrettyPrinted error:&error]; + NSString * string = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + return string; +} ++ (NSDictionary *)stringToDictionary:(NSString *)jsonString{ + NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; + if (jsonData == nil) { + return nil; + } + NSError *error; + NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; + return dict; +} ++ (NSString *)dictionaryToString:(NSDictionary *)dic{ + if ([dic isKindOfClass:[NSDictionary class]]) { + NSError *error; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&error]; + NSString * string = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + return string; + } + else{ + return @""; + } +} + ++ (NSDictionary *)dataToDictionary:(NSData *)jsonData{ + if (![jsonData isKindOfClass:[NSData class]] || jsonData.length < 1) { + return nil; + } + id jsonObj = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:nil]; + if (![jsonObj isKindOfClass:[NSDictionary class]]) { + return nil; + } + return [NSDictionary dictionaryWithDictionary:(NSDictionary *)jsonObj]; +} + + ++ (NSData *)dictionaryToData:(NSDictionary *)dicJson{ + if (![dicJson isKindOfClass:[NSDictionary class]]) { + return nil; + } + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dicJson options:0 error:nil]; + if (![jsonData isKindOfClass:[NSData class]]) { + return nil; + } + return jsonData; +} + ++ (NSString *)dataToHexString:(NSData *)data { + NSUInteger length = data.length; + NSMutableString *result = [NSMutableString stringWithCapacity:length * 2]; + const unsigned char *byte = data.bytes; + for (int i = 0; i < length; i++, byte++) { + [result appendFormat:@"%02X", *byte]; + } + return result; +} + ++ (NSString *)dataToHexString_placeholder:(NSData *)data { + NSUInteger length = data.length; + NSString *placeholder = @" "; + NSMutableString *result = [NSMutableString stringWithCapacity:length * 2]; + const unsigned char *byte = data.bytes; + for (int i = 0; i < length; i++, byte++) { + [result appendFormat:@"%02X%@", *byte, placeholder]; + } + return result; +} + ++ (NSData *)hexStringToData:(NSString *)hexStr { + hexStr = [hexStr stringByReplacingOccurrencesOfString:@" " withString:@""]; + hexStr = [hexStr lowercaseString]; + NSUInteger len = hexStr.length; + if (!len) return nil; + unichar *buf = malloc(sizeof(unichar) * len); + if (!buf) return nil; + [hexStr getCharacters:buf range:NSMakeRange(0, len)]; + + NSMutableData *result = [NSMutableData data]; + unsigned char bytes; + char str[3] = { '\0', '\0', '\0' }; + int i; + for (i = 0; i < len / 2; i++) { + str[0] = buf[i * 2]; + str[1] = buf[i * 2 + 1]; + bytes = strtol(str, NULL, 16); + [result appendBytes:&bytes length:1]; + } + free(buf); + return result; +} + ++ (NSString *)dataToUtf8String:(NSData *)data { + if (data.length > 0) { + return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + } + return @""; +} + + ++ (NSString *)stringTomd5:(NSString *)str { + if (str.length == 0) { + return nil; + } + // 初始化C字符数组 + const char* original_str = (const char *)[[str dataUsingEncoding:NSUTF8StringEncoding] bytes]; + // 盛放数字校验的字符数组(长度为16bytes) + unsigned char digist[CC_MD5_DIGEST_LENGTH]; //CC_MD5_DIGEST_LENGTH = 16 + CC_MD5(original_str, (uint)strlen(original_str), digist); + // NSMutableString* outPutStr = [NSMutableString stringWithCapacity:10]; + NSMutableString* outPutStr = [NSMutableString new]; + for(int i =0; i>8) & 0xff; + unsigned char *pcode = (unsigned char *) (ps + NUM_OF_ORIG_SAMPLE); + unsigned char code; + code = *pcode ++; + + //byte5- byte128: 124 byte(62 sample) adpcm data + for (i=0; i> 3; + + if (code & 4) { + diffq = diffq + step; + } + step = step >> 1; + if (code & 2) { + diffq = diffq + step; + } + step = step >> 1; + if (code & 1) { + diffq = diffq + step; + } + + if (code & 8) { + predict = predict - diffq; + } + else { + predict = predict + diffq; + } + + if (predict > 32767) { + predict = 32767; + } + else if (predict < -32768) { + predict = -32768; + } + + predict_idx = predict_idx + idxtbl[code & 15]; + + if(predict_idx < 0) { + predict_idx = 0; + } + else if(predict_idx > 88) { + predict_idx = 88; + } + + if (i&1) { + code = *pcode ++; + } + else { + code = code >> 4; + } + } + + if (0 && i < NUM_OF_ORIG_SAMPLE) { + *pd++ = ps[i]; + } + else { + *pd++ = predict; + } + } +} + +//例子 +#if 0 +#define MIC_ADPCM_FRAME_SIZE 128 //一包 adpcm 的数据长度 128 byte +#define MIC_SHORT_DEC_SIZE 248 +#define DEC_BUFFER_SIZE (MIC_SHORT_DEC_SIZE<<2) + +unsigned char abuf_dec_wptr; // 0~3 , 4个缓冲 ,循环使用 +unsigned char abuf_mic[MIC_ADPCM_FRAME_SIZE * 4]; //压缩的语音数据adpcm缓冲区 ,4个缓冲 ,每个缓冲区 128 byte , 循环使用 +signed short abuf_dec[DEC_BUFFER_SIZE]; //解压后存放的数据,注意数组类型是 16 bit,4个缓冲,循环使用 + +//abuf_mic 源 , abuf_dec 目的 , 每次解压 128 byte adpcm +adpcm_to_pcm ((signed short *)(abuf_mic + (abuf_dec_wptr & 3) * MIC_ADPCM_FRAME_SIZE), abuf_dec + (abuf_dec_wptr & 3) * MIC_SHORT_DEC_SIZE, MIC_SHORT_DEC_SIZE ); + +#endif + diff --git a/MouseSdk/AiMouseSdk/TlwMouseSdk/adpcm.h b/MouseSdk/AiMouseSdk/TlwMouseSdk/adpcm.h new file mode 100644 index 0000000..0cb25a9 --- /dev/null +++ b/MouseSdk/AiMouseSdk/TlwMouseSdk/adpcm.h @@ -0,0 +1,51 @@ +/******************************************************************************************************** + * @file adpcm.h + * + * @brief This is the header file for BLE SDK + * + * @author BLE GROUP + * @date 06,2020 + * + * @par Copyright (c) 2020, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Unless for usage inside a TELINK integrated circuit, redistributions + * in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of TELINK, nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * TELINK integrated circuit. All other usages are subject to written permission + * from TELINK and different commercial license may apply. + * + * 5. Licensee shall be solely responsible for any claim to the extent arising out of or + * relating to such deletion(s), modification(s) or alteration(s). + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************************************/ +#ifndef ADPCM_H_ +#define ADPCM_H_ + +void adpcm_to_pcm(signed short *ps, signed short *pd, int len); + +#endif /* ADPCM_H_ */ diff --git a/MouseSdk/MouseSdk.xcodeproj/project.pbxproj b/MouseSdk/MouseSdk.xcodeproj/project.pbxproj index 64f1164..65632ae 100644 --- a/MouseSdk/MouseSdk.xcodeproj/project.pbxproj +++ b/MouseSdk/MouseSdk.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 56; + objectVersion = 55; objects = { /* Begin PBXBuildFile section */ @@ -313,7 +313,7 @@ }; }; buildConfigurationList = 18BF1DC52B81AB7C00B8D90F /* Build configuration list for PBXProject "MouseSdk" */; - compatibilityVersion = "Xcode 14.0"; + compatibilityVersion = "Xcode 13.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( diff --git a/MouseSdk/MouseSdk/ViewController.m b/MouseSdk/MouseSdk/ViewController.m index af8900e..035fe32 100644 --- a/MouseSdk/MouseSdk/ViewController.m +++ b/MouseSdk/MouseSdk/ViewController.m @@ -48,7 +48,6 @@ btn.bordered = true; btn.title = @"选择指令"; [btn setTarget:self]; - [btn setAction:@selector(geviceInfoAction)]; [btn setAction:@selector(showPopupMenu:)]; btn.state = 1;