PC相关应用
📎 原始文档:https://www.kdocs.cn/l/ceig0YbkeO9E PC相关应用
本文档旨在指导用户快速使用杰理方案调试PC功能相关的应用,进行快速初步了解。
PC功能指电脑识别UAC(USB Audio)音频设备,芯片会运行到app_pc_task()运行PC相关的处理
概述:
USB (Universal Serial Bus,USB),又称为通用串行总线。各芯片“用于手册”上,可以查看芯片USB OTG模块是Full speed或Hight speed。如AC791N的“用户手册”中复杂设备中有描述:
- Full Speed USB OTG 控制器 - Hight Speed USB OTG 控制器,支持USB HUB
USB模式分为主机模式和从机模式,当做为主机模式的时候,常见应用是去识别U盘,杰理芯片去主动访问U盘设备。当做为从机模式,常见应用就非常多,例如多功能蓝牙音箱,type-c耳机,读卡器等。
代码:
在app_main.c中会进入到app_pc_task(),该模式用于linein功能
应用端开发重点关注..\SDK\apps\common\usb 文件夹下的源文件,
..\cpu\br23\audio_dec文件夹下的audio_dec_pc.c和audio_dec_pc.h
其中 usb_std_class_def.h 定义各设备类的属性,usb_common_def.h用于定义 USB公共属性配置
..\apps\common\usb\device 是USB从机的驱动代码,例如CDC,HID,MSD等
..\apps\common\usb\host 是 USB主机的驱动代码,例如adb,aoa,hid等。
常见问题以及功能示例:
- USB设备类功能开关
#define USB_DEVICE_CLASS_CONFIG (SPEAKER_CLASS|MIC_CLASS|HID_CLASS|MASSSTORAGE_CLASS)
- SPEAKER_CLASS:USB音频
- MIC_CLASS:USB音频
- HID_CLASS :人机交互类,常用于控制UAC的音量调节、上下曲功能 【金山文档】 自定义custom_hid配置
HID配置.docx
695_3.1.0_sdk_add_custom_hid
链接:https://pan.baidu.com/s/1rpEbIgwNkV9S6fVWkFxATQ
提取码:8888
hid实现跟skype for business通信
链接:https://pan.baidu.com/s/1NsFxKQX23JVcGRzWTXBItQ
提取码:8888
- MASSSTORAGE_CLASS:USB大容量存储类,常用于读卡器功能,出盘
- CDC_CLASS:USB串口通信 【金山文档】 CDC配置
CDC配置.docx
- USB描述符
修改电脑上显示的名称
- 修改描述符操作视频(卸载驱动->修改描述符) 改PC描述符视频
修改以下数组。
格式如下:
第1位数据:描述符长度。这里填整个描述符数组的长度;
第2位数据:字符串述符,类型为0x03
第3~n位数据:数据
static const u8 user_stirng[] = {
24,
0x03,
'U', 0x00,
'S', 0x00,
'B', 0x00,
'A', 0x00,
'u', 0x00,
'd', 0x00,
'i', 0x00,
'o', 0x00,
'2', 0x00,
'.', 0x00,
'0', 0x00,
};
- 参考例子 USB
static const u8 user_stirng[] = {
8,
0x03,
'U', 0x00,
'S', 0x00,
'B', 0x00,
};
USB2.0
static const u8 user_stirng[] = {
14,
0x03,
'U', 0x00,
'S', 0x00,
'B', 0x00,
'2', 0x00,
'.', 0x00,
'0', 0x00,
};
中文修改需要使用unicode编码:
网址:http://zhanzhang.cnzzla.com/tool/unicode.php
测试:
static const u8 user_stirng[] = {
6,
0x03,
0x4B, 0x6D,
0xD5, 0x8B,
};
PID&VID
iserialnumber
PC 的ISerialNumber(Serial Number,SN,序列号) 是硬件厂商为每台 PC(或核心硬件,如主板、硬盘、整机等)分配的唯一标识符(通常固化在固件 / BIOS / 硬件芯片中),核心作用是实现设备 / 硬件的 “身份唯一化”,覆盖售后、管理、安全、合规等多场景,以下是具体作用拆解:
一、核心基础作用:硬件身份唯一标识
序列号是 PC / 硬件的 “数字身份证”,全球 / 厂商维度唯一,可精准区分每一台设备 —— 哪怕是同型号、同批次的两台 PC,SN 也绝不重复。这是所有后续作用的基础,解决了 “如何精准定位某一台设备” 的核心问题。
SDK:代码中的返回iserialnumber接口:
void get_iserialnumber_str(u8 *ptr)
{
#if USB_ROOT2
memcpy(ptr, serial_string, serial_string[0]);
#else
extern __attribute__((weak)) u8 *get_norflash_uuid(void);
u8 flash_id[16] = {0};
int i;
u8 bcd;
if (get_norflash_uuid && get_norflash_uuid()) {
ptr[0] = 0x22;
ptr[1] = 0x03;
memset(&ptr[2], 0, 0x20);
memcpy(flash_id, get_norflash_uuid(), 16);
//take 8 bytes from flash uuid
for (i = 0; i < 8; i++) {
bcd = flash_id[i] >> 4;
if (bcd > 9) {
bcd = bcd - 0xa + 'A';
} else {
bcd = bcd + '0';
}
ptr[2 + i * 4] = bcd;
bcd = flash_id[i] & 0xf;
if (bcd > 9) {
bcd = bcd - 0xa + 'A';
} else {
bcd = bcd + '0';
}
ptr[2 + i * 4 + 2] = bcd;
}
} else {
memcpy(ptr, serial_string, serial_string[0]);
}
#endif
}
其他
static const u8 LANGUAGE_STR[] = {
0x04, 0x03, 0x09, 0x04
};
static const u8 product_string[] = {
24,
0x03,
'U', 0x00,
'A', 0x00,
'C', 0x00,
'D', 0x00,
'e', 0x00,
'm', 0x00,
'o', 0x00,
'V', 0x00,
'1', 0x00,
'.', 0x00,
'0', 0x00,
};
static const u8 MANUFACTURE_STR[] = {
34, //该描述符的长度为34字节
0x03, //字符串描述符的类型编码为0x03
0x4a, 0x00, //J
0x69, 0x00, //i
0x65, 0x00, //e
0x6c, 0x00, //l
0x69, 0x00, //i
0x20, 0x00, //
0x54, 0x00, //T
0x65, 0x00, //e
0x63, 0x00, //c
0x68, 0x00, //h
0x6e, 0x00, //n
0x6f, 0x00, //o
0x6c, 0x00, //l
0x6f, 0x00, //o
0x67, 0x00, //g
0x79, 0x00, //y
};
const u8 speakerStringDescriptor[20] = {
20, //该描述符的长度为20字节
0x03, //字符串描述符的类型编码为0x03
'U', 0x00, //U
'S', 0x00, //S
'B', 0x00, //B
' ', 0x00, //
'A', 0x00, //A
'u', 0x00, //u
'd', 0x00, //d
'i', 0x00, //i
'o', 0x00, //o
};
static const u8 micStringDescriptor[30] = {
30, //该描述符的长度为30字节
0x03, //字符串描述符的类型编码为0x03
'U', 0x00, //U
'S', 0x00, //S
'B', 0x00, //B
' ', 0x00, //
'M', 0x00, //M
'i', 0x00, //i
'c', 0x00, //c
'r', 0x00, //r
'o', 0x00, //o
'p', 0x00, //p
'h', 0x00, //h
'o', 0x00, //o
'n', 0x00, //n
'e', 0x00, //e
};
void get_iserialnumber_str(u8 *ptr)
备注:修改之后,连电脑后,需要把声卡驱动卸载,再重装,描述符显示才会更改过来
取消 PC 电脑音量调节
这个不能全部为0,需要选择其他的bit(可以改为1)
USB描述符序号
USB描述符序号功能开启的话,对着电脑同一个USB口插,插第一个机子,显示还是2.0 ,但插第二台,就变成2.0-1 依次类推。
若不想要这个功能,可以按以下截图关闭:

UAC设备OT端描述修改:

我们默认配置的是扬声器描述,如果需要修改为头戴式耳机等描述,按照下图修改,
USB描述符解析:
【金山文档】 USB描述符相关
USB描述符相关.otl
- USB音频参数修改
- 修改USB AUDIO的采样率
#define SPK_AUDIO_RATE 16000
- 修改USB MIC的采样率
#define MIC_AUDIO_RATE 16000
- 单声道改双声道
#define MIC_CHANNEL 2
- 修改SPK位深度
#define SPK_AUDIO_RES 24
///Type 1 Format type descriptor
0x0b, //Length
USB_DT_CS_INTERFACE, //DescriptorType:audio interface descriptor
UAC_FORMAT_TYPE, //DescriptorSubType:Format_type
UAC_FORMAT_TYPE_I, //FormatType:Format type 1
SPK_CHANNEL, //NumberOfChannel
0x03, //SubframeSize:3byte 此处要修改
SPK_AUDIO_RES, //BitsResolution:24bit

//24转16bit--去掉低8bit
u8 *sbuf = (u8 *)ep_buffer;
u32 i, j;
j = 0;
for (i = 0; i < rx_len; i++) {
if ((i % 3) == 0) {
continue;
}
sbuf[j] = sbuf[i];
j++;
}
rx_len = rx_len * 2 / 3;
- 修改SPK采样率96K
#ifndef SPK_AUDIO_RATE
#define SPK_AUDIO_RATE 96000//48000
#endif
#if TCFG_USB_SLAVE_AUDIO_ENABLE
#define AUDIO_DMA_SIZE 576+192 //增大buf
#else
#define AUDIO_DMA_SIZE 0
#endif
701替换media.a库文件:
【金山文档】 media_96K
https://kdocs.cn/l/ckeJmrirgy22
修改采样率数据格式定义
USB音频流位置:


SDK PC事件处理函数
/*----------------------------------------------------------------------------*/
/**@brief pc事件处理
@param event: 事件
@param value: 参数
@return 0:成功
@note
*/
/*----------------------------------------------------------------------------*/
static int usb_device_event_handler(u8 event, int value)
- PC打开网页需求
1、替换hid.c里面的report描述符为 sHIDReportDesc_keyboard 2、在USB_HID_DT_REPORT命令里面注册应该timerout回调函数
sys_timeout_add(NULL, open_website, 1 * 1000);
3、定时时间到了之后会调用 open_website 函数打开网页。
/*
1、替换hid.c里面的report描述符为 sHIDReportDesc_keyboard
2、在USB_HID_DT_REPORT命令里面注册应该timerout回调函数
sys_timeout_add(NULL, open_website, 1 * 1000);
3、定时时间到了之后会调用 open_website 函数打开网页。
*/
static const u8 sHIDReportDesc_keyboard[] = {
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x06, // Usage (Keyboard)
0xA1, 0x01, // Collection (Application)
0x05, 0x07, // Usage Page (Kbrd/Keypad)
0x19, 0xE0, // Usage Minimum (0xE0)
0x29, 0xE7, // Usage Maximum (0xE7)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage Page (LEDs)
0x19, 0x01, // Usage Minimum (Num Lock)
0x29, 0x05, // Usage Maximum (Kana)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x05, 0x07, // Usage Page (Kbrd/Keypad)
0x19, 0x00, // Usage Minimum (0x00)
0x2A, 0xFF, 0x00, // Usage Maximum (0xFF)
0x95, 0x05, // Report Count (5)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0xFF, // Usage Page (Reserved 0xFF)
0x09, 0x03, // Usage (0x03)
0x75, 0x08, // Report Size (8)
0x95, 0x01, // Report Count (1)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x0C, // Usage Page (Consumer)
0x09, 0x00, // Usage (Unassigned)
0x15, 0x80, // Logical Minimum (-128)
0x25, 0x7F, // Logical Maximum (127)
0x95, 0x40, // Report Count (64)
0x75, 0x08, // Report Size (8)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
}
#include "usb/host/usb_hid_keys.h"
static const u16 ascii2kb_remap[128] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x002a, 0x002b, 0x0028, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0 ~ 15
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 16 ~ 31
0x002c, 0x011e, 0x0134, 0x0120, 0x0121, 0x0122, 0x0124, 0x0034, 0x0126, 0x0127, 0x0125, 0x012e, 0x0036, 0x002d, 0x0037, 0x0038, // 32 ~ 47
0x0027, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0133, 0x0033, 0x0136, 0x002e, 0x0137, 0x0138, // 48 ~ 63
0x011f, 0x0104, 0x0105, 0x0106, 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, 0x010f, 0x0110, 0x0111, 0x0112, // 64 ~ 79
0x0113, 0x0114, 0x0115, 0x0116, 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x002f, 0x0031, 0x0030, 0x0123, 0x012d, // 80 ~ 95
0x0035, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, // 96 ~ 111
0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x012f, 0x0131, 0x0130, 0x0135, 0x0000, // 112 ~ 127
};
static void send_key_buffer(u8 *buf)
{
hid_tx_data(0, buf, 8);
os_time_dly(1);
}
/* --------------------------------------------------------------------------*/
/**
* @brief hid keyboard send one key
* @param key - ascii code
* @return NULL
*
* @additional infomation
* modifier key bitmap
* - bit0 left control
* - bit1 left shift
* - bit2 left alt
* - bit3 left gui
* - bit4 right control
* - bit5 right shift
* - bit6 right alt
* - bit7 right gui
*/
/* --------------------------------------------------------------------------*/
static void hid_keyboard_send_onekey(u8 key)
{
static u8 last_key = 0;
u8 buf[8] = {0};
u8 err = 0;
if (key > sizeof(ascii2kb_remap) / sizeof(ascii2kb_remap[0])) {
printf("ERR KEY %x", key);
return;
}
buf[0] = ascii2kb_remap[key] & 0x0100 ? 0x02 : 0x00; //shift key
buf[2] = (u8)(ascii2kb_remap[key] & 0xff);
if ((buf[0] & 0x02) && buf[2] != 0) {
u8 tmpbuf[8] = {0x02};
send_key_buffer(tmpbuf);
}
send_key_buffer(buf);
if ((buf[0] & 0x02) && buf[2] != 0) {
u8 tmpbuf[8] = {0x02};
send_key_buffer(tmpbuf);
}
buf[0] = 0x00; //shift key
buf[2] = 0x00;
send_key_buffer(buf);
}
void open_website(void *p)
{
const char *url = "http://www.zh-jieli.com/\n";
u8 buf[8] = {0};
buf[0] = _KEY_MOD_LMETA;
send_key_buffer(buf);
buf[2] = (ascii2kb_remap['r'] & 0xff);
send_key_buffer(buf);
memset(buf, 0, 8);
send_key_buffer(buf);
send_key_buffer(buf);
for (int i = 0; i < strlen(url); i++) {
hid_keyboard_send_onekey(url[i]);
}
}
WINDOW7电脑PC驱动安装过程中复位死机 给PC安装了具备 MASSSTORAGE、audio和HID的设备,然后再把固件程序去掉mass功能,不管是重新下载代码进入机器,还是把windows7再卸载MASS 声卡驱动,window7电脑还是会蓝屏复位。但同样一个电脑,换一个IC又正常。
因为WINDOW安装获取了唯一的序列号,不管怎么下载都是一样。所以最佳的方法两种:
第一种:
修改上面例子的 PID & VID
第二种:
把设备驱动的残留彻底卸载掉。
PC模式,电脑上的扬声器平衡项,左前(两声道都有作用),右前(没有作用)
AC6082A2 V1.2.2 AC6082A用ac608n_soundbox_sdk_v1.2.2包 修改audio_dec_pc.c文件,增加立体声平衡音量控制(把有修改后的部分更新到程序上)
链接:https://pan.baidu.com/s/1dQHKuTnlJxEDYtPkEJOzmg
提取码:jielAC7000N 用AC700N_earphone_release_V1.3.0 包做PC模式 修改audio_dec_pc.c、audio_dvol.c、audio_dvol.h文件,增加立体声平衡音量控制(把有修改后的部分更新到程序上)
链接:【金山文档】 AC700N_earphone_release_V1.3.0_PC模式扬声器平衡项左前两声道都有作用右前无作用问题修改
https://kdocs.cn/l/cjBCKirF1vq6PC模式,电脑上的显示卡设备名字修改 参考文件系统中设置卷标的方法(链接:MUSIC 模式相关应用.otl)
PC模式,电脑上取消平衡选项
修改如下:
可视化701N耳机SDK 实现电脑平衡控制耳机左右声道音量 701N300_0217_PC音量分左右.rar
修改细节:


type-c线控耳机的按键驱动Demo及说明 Demo链接【金山文档】 AC700N_earphone_release_V1.3.6-type-c按键驱动Demo
https://kdocs.cn/l/cvyofIFjxIRf
按键操作说明
PP按键单击-播放暂停
PP按键双击及三击-切换歌曲(手机APP做的处理)
PP按键长按-开启语音助手(安卓手机需要进入语音助手设置界面打开长按播放键打开语音助手)
VOL-单击-音量减
VOL-长按-音量快速减
VOL+单击-音量+
VOL+长按-音量快速加
- type-c接口硬件设计要点

可以参考以下原理图:
AC1289A_TYPE-C耳机V1.2.pdf
或者使用带 OTG转接头接USB头:
HID Report的修改说明及解析 【金山文档】 PC模式下的HID Report修改说明及解析
PC模式下的HID Report修改说明及解析.otl插入PS4播放音频声音较小的问题修改 以下补丁基于ac608n_soundbox_sdk_v1.2.2修改,其他SDK版本,如695N,696N等可以参考修改。
【金山文档】 PS4mode音量较小修改
PS4mode音量较小修改.rar添加MAC&WINDOWS&PS系统识别
功能说明:
1、获取连接的系统 usb_get_host_type()

具体修改内容:【金山文档】 0001-MAC-WINDOWS-PS
Git
17. iPhone15 短按PP按键支持来电接听挂断 iPhone15相比普通的安卓手机,默认的描述符iPhone15发送短按PP指令(即发一次08 00再发一次00 00)指令是无法触发手机的接挂功能,必须引入telephony下面的call control USEAGE 中的flash属性才能触发,具体修改如下:
- 找到发送hid指令对应的.c,dongle和耳机的pc模式用的.c文件有出入,例如此处用的是耳机的hid.c
- 找到自己对应的hid report数组,通过get_hid_report_desc_len 函数去找到具体引用的哪个hid report数组

- 修改对应数组里面的hid report,默认是单个hid report,且默认的命令发送不带hid report id,参考如下修改
//从这里开始是默认的
USAGE_PAGE(1, CONSUMER_PAGE),
USAGE(1, CONSUMER_CONTROL),
COLLECTION(1, APPLICATION),
0x85, 0x06, // Report ID (6)->新增这个hid report id
LOGICAL_MIN(1, 0x00),
LOGICAL_MAX(1, 0x01),
USAGE(1, VOLUME_INC),
USAGE(1, VOLUME_DEC),
USAGE(1, MUTE),
USAGE(1, PLAY_PAUSE),
USAGE(1, SCAN_NEXT_TRACK),
USAGE(1, SCAN_PREV_TRACK),
USAGE(1, FAST_FORWARD),
USAGE(1, STOP),
USAGE(1, TRACKING_INC),
USAGE(1, TRACKING_DEC),
USAGE(1, STOP_EJECT),
USAGE(1, VOLUME),
USAGE(2, BALANCE_LEFT),
USAGE(2, BALANCE_RIGHT),
USAGE(1, PLAY),
USAGE(1, PAUSE),
REPORT_SIZE(1, 0x01),
REPORT_COUNT(1, 0x10),
INPUT(1, 0x42),
END_COLLECTION,
//到这里结束都是默认的
//以下是新增的hid report
0x05, 0x0B, // Usage Page (Telephony)
0x09, 0x01, // Usage (Phone)
0xA1, 0x01, // Collection (Application)
0x85, 0x07, // Report ID (7)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x09, 0x21, // Usage (Flash)->这个影响iPhone来电能否按键接听
0x09, 0x2F, // Usage (Phone Mute)
0x09, 0x50, // Usage (Speed Dial)
0x09, 0xCF, //
0x09, 0xCF, //
0x09, 0xCF, //
0x09, 0xCF, //
0x09, 0xCF, //
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x07, // Input (Const,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
END_COLLECTION,
- 按照第3步修改后,hid report里面存在两个不同的hid report id和对应的操作描述,具体原理看: PC模式下的HID Report修改说明及解析.otl,改完后修改默认的按键操作的HID发送函数
void adapter_avctp_key_handler(u32 hid_key)
{
//注释里面的内容是标准SDK的写法
// u16 key_buf = hid_key;
// usb_g_intr_write(0, KEYBOARD_HID_EP_IN, ((const u8 *)&key_buf), 2);
// key_buf = 0;
// usb_g_intr_write(0, KEYBOARD_HID_EP_IN, ((const u8 *)&key_buf), 2);
u8 key_buf[3] = {0x06, 0x00, 0x00};
key_buf[1] = (u8)(hid_key & 0xff);
printf("%s->key_buf:\n", __func__);
put_buf(key_buf, 3);
usb_g_intr_write(0, KEYBOARD_HID_EP_IN, key_buf, 3);
os_time_dly(2);
printf("%s->key_buf:\n", __func__);
put_buf(key_buf, 3);
key_buf[1] = 0;
usb_g_intr_write(0, KEYBOARD_HID_EP_IN, key_buf, 3);
}
- 停止和启动PC检测的接口
extern void usb_detect_timer_del();//停止检测
extern void usb_detect_timer_add();//启动检测
- PC模式增加Teams后台唤起功能 可以参考以下链接
PC模式下增加Teams唤起功能
PC模式下增加Teams唤起功能.otl - 第一次默认音量设置

- 键盘组合按键模拟---呼叫 Win11 Copilot
- 添加 Keyboard 报告描述符, 参考 PC打开网页需求 。
- 发送组合按键 HID 报告, 左 Shift + 左 Windows 键 + F23
void hid_key_lshift_lwin_f23(void)
{
u8 buf[8] = {0};
// 设置修饰键:左 Shift(位 1)和左 Windows 键(位 3)
buf[0] = _KEY_MOD_LSHIFT | _KEY_MOD_LMETA;
// 设置普通按键:F23
buf[2] = _KEY_F23;
// 发送按键按下事件
send_key_buffer(buf);
// 释放所有按键
memset(buf, 0, sizeof(buf));
send_key_buffer(buf);
}
FAQ
2.1 AC695 PC模式下播放提示音后异常
修改方法:
sdk\cpu\br23\audio_dec\audio_dec_pc.c的uac_audio_start() 函数添加 sample_rate_set =0 如下:
#if (TCFG_DEC2TWS_ENABLE)
bt_tws_sync_volume();
#endif
// 开始解码
dec->start = 1;
err = audio_decoder_start(&dec->pcm_dec.decoder);
if (err) {
goto __err3;
}
dec->state = 0;
dec->cnt = 0;
dec->check_data_timer = sys_hi_timer_add(NULL, audio_pc_check_timer, 10);
#if PC_SYNC_BY_DAC_HRP
in_points = 0;
out_points = 0;
last_hrp = 0;
dac_start_flag = 0;
sample_rate_set = 0;
usb_icnt = 0;
#endif // PC_SYNC_BY_DAC_HRP
clock_set_cur();
return 0;
__err3:
dec->start = 0;
pc_eq_drc_close(dec->eq_drc);
#if TCFG_EQ_DIVIDE_ENABLE
pc_rl_rr_eq_drc_close(dec->eq_drc_rl_rr);
audio_vocal_tract_synthesis_close(&dec->synthesis_ch_fl_fr);
audio_vocal_tract_synthesis_close(&dec->synthesis_ch_rl_rr);
audio_vocal_tract_close(&dec->vocal_tract);
channel_switch_close(&dec->ch_switch);
#endif
2.2 AC695N 系列优化电脑长时间播放没声音的处理
修改msd_mcu2usb函数,添加多次重发的机制
apps\common\usb\device\msd.c
u32 msd_mcu2usb(const struct usb_device_t *usb_device, const u8 *buffer, u32 len)
{
usb_dev usb_id = usb_device2id(usb_device);
int ret;
for(int i = 0; i < 3; i++){
ret = usb_g_bulk_write(usb_id, MSD_BULK_EP_IN, buffer, len);
if(ret){
break;
}
}
return ret;
// return usb_g_bulk_write(usb_id, MSD_BULK_EP_IN, buffer, len);
}
2.3 USB线过长导致插某些电脑无法识别处理
1、开启USB口强驱功能:
2、VDDIO 提高到3.6V档位
2.4 PID/VID/SN机器相同会导致电脑重启
可能电脑里面的驱动程序没有完全卸载 (参考以下操作进行)
Win7系统如何卸载残留无用驱动设备_pan0755的博客-CSDN博客
2.5 AC700N V132,PC模式开启CDC在线调EQ导致插入电脑设备异常
原因:CDC导致的电脑识别的描述符混乱,按照如下修改添加部分描述符将AUDIO CLASS的描述符包起即可
memcpy(tptr, (u8 *)uac_spk_interface_association, sizeof(uac_spk_interface_association));
tptr[2] = *cur_itf_num;
tptr[3] = 3;
tptr += sizeof(uac_spk_interface_association);//0x09
2.6 AC700N V132,PC模式在线调EQ调音工具打开串口通信显示命令超时
pc模式缺少在线eq的相关事件流程,如下修改即可
#if (TCFG_ONLINE_ENABLE || TCFG_CFG_TOOL_ENABLE)
} else if ((u32)event->arg == DEVICE_EVENT_FROM_CFG_TOOL) {
extern int app_cfg_tool_event_handler(struct cfg_tool_event * cfg_tool_dev);
app_cfg_tool_event_handler(&event->u.cfg_tool);
#endif
2.7 AC700N V130之后版本USB PC模式下开启通话算法方法
- audio_usb_mic.c内使能USB_MIC_AEC_EN开启相关通话算法流程

- audio_usb_mic.c的usb_audio_mic_open()函数中的audio_aec_open内开启相关算法模块


- 单麦的audio_aec.c\双麦audio_aec_dms.c内的aec_open()函数中加载AEC模块代码
注意:如果算法模块还开启了NLP\AEC等回音消除模块,则需要进入audio_aec.c(单麦)或者audio_aec_dms.c(双麦)中参考路数据变采样的变量置1,V130版本仅支持单麦USB回音消除,双麦USB回音消除请用V130之后的版本。
2.8 AC700N V132 USB CDC后台串口声学产测
目前AC700N V132SDK已做好CDC后台串口调音,因此在此基础上添加CDC后台串口进行产测,需要产测上位机做好USB通信。
demo见此链接(V132之前的版本可根据该demo自行移植)。
【金山文档】 AC700N_earphone_release_V1.3.2-添加CDC产测
https://kdocs.cn/l/csn98Ygdc5n1
2.9 AC696X 卡和U盘复用时卡不在线时插PC要能识别修改
当卡和U盘复用时,默认SDK是配置关闭PC模式的。如果强制开启来的话,插PC是无法检测到PC模式的。但通过按键切模式,可以切到PC模式。如果想要做到插PC能自动识别,需要对照以下task_pc.c文件修改 (注意:仅支持卡不在线时,插PC识别)
【金山文档】 AC696X 卡和U盘复用时卡不在线时插PC要能识别修改
https://kdocs.cn/l/cjq7iscjE5mr
2.10 701 151SDK,USBDP口复用UART,WIN7电脑不识别处理方法
【金山文档】 701 151SDK,USBDP口复用UART,WIN7电脑不识别处理方法
701 151SDK,USBDP口复用UART,WIN7电脑不识别处理方法.otl
2.11 695-310sdkPC模式,某些时候电脑会下发多个开关usb-mic的指令,添加延时过滤机制
例如:在电脑设置pcmic的界面会下发5对开关mic,导致频繁切换
修改方法:在695sdk上移植701uac,接收开关mic命令延迟机制(参考701sdk的代码)
替换SDK\apps\common\usb\device\uac_stream.c中的uac_mic_stream_open()和uac_mic_stream_close()
static u32 mic_close_tid = 0;
static u8 mic_sw;
u32 uac_mic_stream_open(u32 samplerate, u32 frame_len, u32 ch)
{
mic_sw = 1;
if (mic_stream_is_open) {
r_printf("-uac_mic_is_opened-\n");
return 0;
}
/* mic_tx_handler = NULL; */
log_info("%s", __func__);
struct sys_event event;
event.type = SYS_DEVICE_EVENT;
event.arg = (void *)DEVICE_EVENT_FROM_UAC;
event.u.dev.event = USB_AUDIO_MIC_OPEN;
event.u.dev.value = (int)((ch << 24) | samplerate);
mic_stream_is_open = 1;
#if !UAC_DEBUG_ECHO_MODE
sys_event_notify(&event);
#endif
return 0;
}
static void uac_mic_stream_close_delay()
{
mic_close_tid = 0;
if (!mic_sw) {
} else {
return ;
}
log_info("%s", __func__);
struct sys_event event;
event.type = SYS_DEVICE_EVENT;
event.arg = (void *)DEVICE_EVENT_FROM_UAC;
event.u.dev.event = USB_AUDIO_MIC_CLOSE;
event.u.dev.value = (int)0;
mic_stream_is_open = 0;
#if !UAC_DEBUG_ECHO_MODE
sys_event_notify(&event);
#endif
}
void uac_mic_stream_close()
{
mic_sw = 0;
if (mic_stream_is_open == 0) {
return ;
}
log_info("%s", __func__);
//FIXME:
//未知原因出现频繁开关mic,导致出现audio或者蓝牙工作异常,
//收到mic关闭命令后延时1s再发消息通知audio模块执行关闭动作
//如果在1s之内继续收到usb下发的关闭命令,则继续推迟1s。
if (mic_close_tid == 0) {
mic_close_tid = sys_hi_timeout_add(NULL, uac_mic_stream_close_delay, 1000);
} else {
sys_hi_timeout_modify(mic_close_tid, 1000);
}
}
2.12 不同设备接到电脑上要让电脑认为是同一个设备修改点
此处改为1
2.13JL701N USB口给苹果手机充电,需要解锁手机屏幕才能充电问题
修改方法:(苹果充电需要我们做主机,并且发一个控制传输的命令)
增加的代码部分:
#if 1 //////////////////////增加以下代码/////////////////////
extern int usb_control_msg(struct usb_host_device *host_dev,u8 request,u8 requesttype,u16 vale,u16 index,void *data,u16 size);
if(device_desc.idVendor == 0x5ac)
{
usb_control_msg(host_dev,0x40,0x40,0x01f4,0x05dc,NULL,0);
private_data->status = 1;
printf(">>>>>>>>>>>>>>>>>>>>>>>>>>iphone!!!!\n");
return DEV_ERR_NONE;
}
#endif // 1 //////////////////////end/////////////////////
2.14 AC701N V160/161版本PC模式主机识别设备慢,win7系统播放音乐概率无声问题
修改msd.c文件中的stall_inep,stall_outep函数中的ot值,或者在函数的循环中加入延时:

2.15 AC701N V135版本PC模式添加低功耗休眠功能后,按键发送USB HID播歌命令出现无法唤醒手机
问题原因:
1、设备唤醒命令没有及时响应。
2、按键初始化没有初始化notify_value,导致notify_value是0,而唤醒按键value是0,所以会忽视第一次按键按下事件。
解决方案:
- 修改唤醒延时时间。

- 在按键初始化时把按键的notify_value设置为NO_KEY解决设备第一次上电丢失按键按下事件。

2.16 wireless_mic_sdk-v1.4.1_duplex HID按键无法唤醒智能语音助手
1.HID按键最多加16个,需选择一个替换为0XCF(语音唤醒键值)。
2.按键调用对应的BIT值,即原本被替换的hid_key。
3.语音按键是需要长按的,可以如图增加延时实现。不过不是很建议使用延时的方式实现,改成用户按下就发键值,抬起就发00(也就是延时之后的那个键值),这样兼容性会更好。
gitlab地址:Files · feature_open_SIRI · 自由品牌 / 客户支持 / SOUNDBOX / wireless_mic / wireless_mic_sdk · GitLab
2.17 USB-Audio-pc声卡模式: 电脑没有开播放器或者开着播放器(没播放过),操作音箱音量加减,获取不到电脑进度条音量值
注释以下
示例
- usb hid keyboard 和 CONSUMER_PAGE 联合使用 AC695N_soundbox_sdk_release_3.1.2_case_usb_hid_multi_report.zip