KDocs 研发资料库
  • 音频技术应用文档入口汇总
  • 杰理WINDOWS环境安装及其他事项
  • LINUX安装和编译
  • Linux环境编译SDK教程(ubuntu18.04)
  • 音频类补丁汇总表
  • 认证资料获取汇总(最新资料后台会更新)
  • 《Hi-Res申请指南v1.0》
  • FreeRTOS 开源协议版本
  • uCOS 开源协议版本信息
  • 各个模块关键资料汇总
  • 软件调试方法
  • Makefile编译
  • 提bug的规范
  • 常规设备使用指导
  • 对外特别发布开发注意点信息汇总
  • AD697X软件问题整理
  • AC700N软件问题整理
  • AC701X耳机软件问题整理
  • 951&961软件问题整理
  • AC104X软件问题整理
  • AC128N问题整理文档
  • 可视化工具调试问题整理
  • 耳机资料汇总
  • AC704N、 AC705N相关应用
  • AC695N&AC696N&AC608N音箱问题整理
  • JL701N音箱问题整理
  • AC692X软件问题整理
  • AC706N音箱问题整理
  • JL701N音箱问题整理(可视化工具SDK)
  • JL703N音箱问题整理
  • JL709N(JL689N)音箱问题整理
  • JL7094系列-入门到进阶开发指导
  • AC210N音箱问题整理
  • 无线麦系列版本支持指南
  • AW32N无线麦问题整理
  • lAD697X&JL701X 无线麦软件共性问题整理
  • AC706N无线麦问题整理
  • AW36N无线麦问题整理
  • AC710X无线麦问题整理
  • 唤醒源获取及唤醒IO设置
  • 电源
  • LVD
  • 长按复位配置方法
  • 低功耗应用
  • TIMER
  • UART
  • SPI
  • 内部FLASH空间添加用户自定义区域
  • IIC
  • GPIO
  • MCPWM
  • SD&U盘
  • 时钟&晶振
  • GPCNT
  • IO口crossbar映射功能
  • 文件系统使用总结
  • 复用应用
  • LINEIN_AUX相关应用
  • IIS音频接口应用
  • SPDIF模式相关(HDMI_ARC、光纤、同轴)
  • PDM LINK
  • 外设相关应用
  • 蓝牙相关
  • 杰理蓝牙距离调试文档
  • TWS耳机配对方式使用及生产把控指南
  • GFP谷歌快连及其认证流程指引
  • 蓝牙发射器(bt_emitter)相关
  • BLE应用
  • 关于提升BLE传输速率说明
  • BLE测试数据
  • MUSIC 模式相关应用
  • MIDI音乐实现
  • PC相关应用
  • FM相关应用
  • AC695N_AC696N FM天线ESD静电防护措施说明V2.0_20250107
  • fm应用详细设计说明书
  • 杰理FM硬件指南-20230315
  • ADC模块
  • AUDIO相关应用
  • 新Tools的音效调试使用
  • 混响应用使用说明
  • 音效调式
  • 音箱耳机低音小音量增强实现方法
  • DAC输出功率调试
  • DAC性能测试指南
  • 针对各类底噪、电流声分析流程
  • 录音相关应用
  • OPUS编解码相关
  • RTC相关应用
  • 升级相关
  • UI相关应用
  • 通话调试流程指南
  • 通话相关应用
  • 省电容mic使用手册
  • 如何测试验证手表通话系统的语音失真 V1.0
  • AC695X_AC696X_AD697X 常见通话问题处理参考资料
  • 通话调试问题确定步骤
  • 内置触摸调试指南
  • 低功耗内置触摸介绍V2.2
  • 触摸相关文档
  • AC697X、AC698X内置触摸调试及整改方法V1.0
  • 产测相关应用
  • AC63X BLE DUT测试介绍
  • 兆华序列使用简易说明
  • JL_1T2蓝牙测试盒音频文件更换说明
  • ENC相关应用入口汇总
  • ANC相关应用入口汇总
  • JL DMS通话调试手册-V3.9.4
  • ANC-ENC结构设计要点-20240407
  • 半入耳式ANC耳机器件选型与结构设计指南V1.0
  • JL 耳道自适应调试指南
  • ANC相关问题处理
  • ANC调试文档
  • 评估蓝牙耳机通话上行降噪性能的方法 V1.0 (2)
  • FCC 或者 BQB 认证相关应用
  • BQB profile 测试中常遇到的问题点汇总
  • 蓝牙参数整理20210811
  • 杰理科技认证问题参考
  • 无线音频产品开发指南
  • 无线麦系列从入门到进阶开发指导
  • 量产烧录相关说明
  • 一拖八烧录器远程过程调用说明
  • 量产相关建议
  • EffectTool(eq)调试工具说明文档
  • AC897AD697系列的EQ调试方法-V3
  • 杰理调音指南-20220622
  • 音效模块总结
  • 简要调音步骤指引(可视化)
  • 耳机充电与通信调试指南
  • 充电仓硬件调试指南
  • 充电仓软件问题整理
  • AC951常用说明
  • AC951_AC961_开发板使用说明V1.0
  • 彩屏仓AC982 入门指导及FAQ
  • 蓝牙音频APP相关应用
  • 手机APP的简介和开发流程
  • 蓝牙音频系列-硬件设计指南
  • 静电测试及整改方法-20220706
  • TWS耳机底噪整改指南V1.2
  • 杰理蓝牙距离调试文档
  • 蓝牙RF硬件设计与调试V1.1-20250219
  • AC695N_AC696N FM天线ESD静电防护措施说明V2.0_20241228
  • 音效调试指南
  • 无线话筒K歌音箱标准开发流程
  • 杰理科技 700N TWS耳机产品标准-202303
  • 杰理科技 701N 广播产品标准-202303
  • JL-HAT ANC高效产测自适应
  • 无线话筒测试板使用介绍
  • 一拖八频偏校准使用说明
  • 领夹麦产测工具使用介绍
  • Dongle量产测试说明
  • Dongle+Tws或头戴式 SDK通过工具绑定配对功能说明文档
  • 双麦ENC产测宏配置验证方法 V1.0
  • JL耳机方案麦克风声学测试指令_V1.0
  • JL耳机方案麦克风声学测试指令_V2.0
  • JL_ENC自动测试命令_V0.0.1
  • JL蓝牙测试盒用例说明
  • LDAC自测环境搭建_ubuntu
  • 延迟小板使用手册
  • 杰理库文件的制作及添加实现过程
  • 关于 AC635N&AC636N系列免晶振兼容性补丁 说明
  • 关于 AC63系列VM兼容性修复补丁_20250224 说明
  • 关于 AC632N &AE632N_ 蓝牙& 低功耗兼容性修复补丁 说明
  • AD698N和AC638N电压优化补丁V3说明
  • 关于 AC635N&AC636N漏电和E&G版兼容联合补丁 说明
  • AD698N和AC638N电压优化补丁V2说明
  • 702相关应用
  • 2024-4-30 发布歌词显示SDK开发注意事项
  • BQB RF & FCC 认证测试固件问题汇总及源码
  • BQB profile 测试中常遇到的问题点汇总
  • 进dut测试模式方法及固件
  • 704-频偏修改bin文件合集
  • 701手表BQB PROFILE认证注意事项
  • 认证的干扰规避整改
  • 海外CRA认证报告生成说明
  • JL700N可视化工具问题处理文档
  • JL701X可视化工具问题处理文档
  • JL701N_earphone_release_v1.6.0_ANC 低功耗问题补丁
  • JL708X可视化工具问题处理文档
  • JL709N可视化工具问题处理文档
  • JLstudio可视化工具使用说明
  • 一拖二-串口_蓝牙_app在线EQ、通话参数及调试方式和内置触摸调试
  • 可视化JL701M_DONGLE_SDK添加MIC为发射源
  • 可视化JL701M_DONGLE_SDK添加按键切换usb audio与MIC发射源
  • JL701M_DONGLE_SDK_1.0.0_dongle输入linein输出dac
  • 701可视化_a2dp_to_le_demo说明
  • 耳机系列demo汇总
  • JL7018F&JL7006F_7003F AUX IIS
  • 一键连接应用
  • 普通SDK动态开关一拖二功能
  • 蓝牙分析仪(EllisysBluetoothAnalyzer)抓包例程
  • TWS配对常见应用
  • APP自定义按键的demo
  • AC700N 播歌双EQ DEMO示例及说明
  • AC698V164 MIC与蓝牙音乐共同输出DAC demo
  • 添加第三方算法以及多算法授权流程
  • 空间音频配置方法
  • 普通高低电平TWS耳机控制通讯
  • 入耳检测状态更新demo解析
  • 资源优化(非可视化的SDK)
  • 资源优化(可视化SDK)
  • 翻译耳机、语音识别应用demo
  • 耳机抗干扰问题排查和优化
  • AC698D2 抗干扰优化
  • AC696X软件问题整理
  • AC695X软件问题整理
  • AC695X软件问题整理_1722249702
  • AC608X软件问题整理
  • JL701N_2T1_DUPLEX 应用软件问题汇总
  • le_audio_1.0.0_patch05 以及之前的版本IRkey 功能异常修改
  • AC706N-le_audio-200SDK有线_无线麦录音demo
  • jl701n_le_audio_v200patch02 IO串口升级修改串口单次发送字节长度的修改办法
  • 703创建IIS 输入dac输出音频流demo
  • 703将媒体流音频同时上传PC_mic录音demo实现
  • 703四路IIS输入输出demo
  • 底噪调试
  • AW328A烧录说明
  • 文档合集
  • AC706N_wireless_mic_release_PATCH_20240712 补丁 说明
  • AC706N_wireless_mic_release_PATCH_20240726 补丁 说明
  • AC706N_wireless_mic_release_V1.0.0、1.0.1、1.0.2 补丁 说明
  • AC706N_wireless_mic_release_V1.1.2 中的2T1应用 RX端不绑定配对,TX端实现绑定配对的修改方法
  • 各系列省晶振实现方法
  • iis tx rx说明文档
  • spdif信号
  • 蓝牙电话本
  • 安卓手机同步时间补丁
  • CDC配置
  • PC模式下增加Teams唤起功能
  • 杰理HDMIARC开发实现过程
  • AC701N patch06之前的版本用第三方算法节点实现新版本的pcm delay节点功能
  • (K歌音箱)各SDK音效配置相关说明
  • 长文件录音
  • 点阵屏歌词字库相关(蓝牙歌词,普通歌词)
  • 字模提取工具说明
  • 音箱可视化彩屏-入门到进阶开发指导
  • 彩屏LVGL UI设计及工具使用
  • 使用内部UI框架进行UI调试的系列步骤
  • AD101C使用强制升级工具spi 烧录不了问题处理(测试版本)
  • AD161扩展灯板说明文档
  • 歌词显示器开发注意项
  • 使用硬件数字增益控制通话下行音量(可视化)
  • 杰理小牛产测资料
  • ENC配置说明
  • 通话调试流程指引
  • ANC相关功能demo
  • 无线麦硬件资料汇总
  • 无线麦相关应用
  • 无线麦复杂功能补丁包汇总
  • 无线话筒形态SDK程序&开发经验&问题点分享
  • 双模式结合应用问题汇总
  • 无线麦距离优化案例
  • 无线麦系列中的双工形态(duplex)演变开发对讲机方案开发资料
  • 音箱入门到进阶指导文档(编写中)
  • 蓝牙耳机品控和生产技巧
  • 982过_欠压标志获取异常
  • 如何获取最新涂鸦SDK及库文件
  • 无线话筒K歌音响-调音标准流程
  • 无线话筒产测流程

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等。

常见问题以及功能示例:

  1. 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
  1. 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编码:
image 网址:http://zhanzhang.cnzzla.com/tool/unicode.php
测试:

static const u8 user_stirng[] = {
    6,
    0x03,
    0x4B, 0x6D,
    0xD5, 0x8B,
};

PID&VID

image

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)
imageimage

USB描述符序号

USB描述符序号功能开启的话,对着电脑同一个USB口插,插第一个机子,显示还是2.0 ,但插第二台,就变成2.0-1 依次类推。
若不想要这个功能,可以按以下截图关闭:

image

UAC设备OT端描述修改:

imageimage 我们默认配置的是扬声器描述,如果需要修改为头戴式耳机等描述,按照下图修改,
image

USB描述符解析:

【金山文档】 USB描述符相关
USB描述符相关.otl

  1. 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

image

 //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
修改采样率数据格式定义
image

  1. USB音频流位置: imageimage

  2. SDK PC事件处理函数

/*----------------------------------------------------------------------------*/

/**@brief    pc事件处理

@param    event: 事件

@param    value: 参数

@return   0:成功

@note

*/

/*----------------------------------------------------------------------------*/

static int usb_device_event_handler(u8 event, int value)

  1. 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]);
    }
}

  1. WINDOW7电脑PC驱动安装过程中复位死机 给PC安装了具备 MASSSTORAGE、audio和HID的设备,然后再把固件程序去掉mass功能,不管是重新下载代码进入机器,还是把windows7再卸载MASS 声卡驱动,window7电脑还是会蓝屏复位。但同样一个电脑,换一个IC又正常。
    因为WINDOW安装获取了唯一的序列号,不管怎么下载都是一样。所以最佳的方法两种:
    第一种:
    修改上面例子的 PID & VID
    第二种:
    把设备驱动的残留彻底卸载掉。
    image

  2. PC模式,电脑上的扬声器平衡项,左前(两声道都有作用),右前(没有作用)

  3. AC6082A2 V1.2.2 AC6082A用ac608n_soundbox_sdk_v1.2.2包 修改audio_dec_pc.c文件,增加立体声平衡音量控制(把有修改后的部分更新到程序上)
    链接:https://pan.baidu.com/s/1dQHKuTnlJxEDYtPkEJOzmg
    提取码:jiel

  4. AC7000N 用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/cjBCKirF1vq6

  5. PC模式,电脑上的显示卡设备名字修改 参考文件系统中设置卷标的方法(链接:MUSIC 模式相关应用.otl)

  6. PC模式,电脑上取消平衡选项 image 修改如下:
    image

  7. 可视化701N耳机SDK 实现电脑平衡控制耳机左右声道音量 701N300_0217_PC音量分左右.rar
    修改细节:
    imageimageimage

  8. 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+长按-音量快速加

  1. type-c接口硬件设计要点

image

可以参考以下原理图:
AC1289A_TYPE-C耳机V1.2.pdf

或者使用带 OTG转接头接USB头:
image

  1. HID Report的修改说明及解析 【金山文档】 PC模式下的HID Report修改说明及解析
    PC模式下的HID Report修改说明及解析.otl

  2. 插入PS4播放音频声音较小的问题修改 以下补丁基于ac608n_soundbox_sdk_v1.2.2修改,其他SDK版本,如695N,696N等可以参考修改。
    【金山文档】 PS4mode音量较小修改
    PS4mode音量较小修改.rar

  3. 添加MAC&WINDOWS&PS系统识别

功能说明:
1、获取连接的系统 usb_get_host_type()

imageimage 具体修改内容:【金山文档】 0001-MAC-WINDOWS-PS
Git
17. iPhone15 短按PP按键支持来电接听挂断 iPhone15相比普通的安卓手机,默认的描述符iPhone15发送短按PP指令(即发一次08 00再发一次00 00)指令是无法触发手机的接挂功能,必须引入telephony下面的call control USEAGE 中的flash属性才能触发,具体修改如下:

  1. 找到发送hid指令对应的.c,dongle和耳机的pc模式用的.c文件有出入,例如此处用的是耳机的hid.c
  2. 找到自己对应的hid report数组,通过get_hid_report_desc_len 函数去找到具体引用的哪个hid report数组 image
  3. 修改对应数组里面的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,
  1. 按照第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);
}
  1. 停止和启动PC检测的接口
extern void usb_detect_timer_del();//停止检测
extern void usb_detect_timer_add();//启动检测
  1. PC模式增加Teams后台唤起功能 可以参考以下链接
    PC模式下增加Teams唤起功能
    PC模式下增加Teams唤起功能.otl
  2. 第一次默认音量设置 image
  3. 键盘组合按键模拟---呼叫 Win11 Copilot
  4. 添加 Keyboard 报告描述符, 参考 PC打开网页需求 。
  5. 发送组合按键 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口强驱功能:
image

2、VDDIO 提高到3.6V档位

2.4 PID/VID/SN机器相同会导致电脑重启

可能电脑里面的驱动程序没有完全卸载 (参考以下操作进行)
Win7系统如何卸载残留无用驱动设备_pan0755的博客-CSDN博客

2.5 AC700N V132,PC模式开启CDC在线调EQ导致插入电脑设备异常

原因:CDC导致的电脑识别的描述符混乱,按照如下修改添加部分描述符将AUDIO CLASS的描述符包起即可
image

    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的相关事件流程,如下修改即可
image

#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模式下开启通话算法方法

  1. audio_usb_mic.c内使能USB_MIC_AEC_EN开启相关通话算法流程 image
  2. audio_usb_mic.c的usb_audio_mic_open()函数中的audio_aec_open内开启相关算法模块 imageimage
  3. 单麦的audio_aec.c\双麦audio_aec_dms.c内的aec_open()函数中加载AEC模块代码 image 注意:如果算法模块还开启了NLP\AEC等回音消除模块,则需要进入audio_aec.c(单麦)或者audio_aec_dms.c(双麦)中参考路数据变采样的变量置1,V130版本仅支持单麦USB回音消除,双麦USB回音消除请用V130之后的版本。
    image

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
image

2.13JL701N USB口给苹果手机充电,需要解锁手机屏幕才能充电问题

修改方法:(苹果充电需要我们做主机,并且发一个控制传输的命令)
image

增加的代码部分:

#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值,或者在函数的循环中加入延时:
imageimage

2.15 AC701N V135版本PC模式添加低功耗休眠功能后,按键发送USB HID播歌命令出现无法唤醒手机

问题原因:
1、设备唤醒命令没有及时响应。
2、按键初始化没有初始化notify_value,导致notify_value是0,而唤醒按键value是0,所以会忽视第一次按键按下事件。
解决方案:

  1. 修改唤醒延时时间。 image
  2. 在按键初始化时把按键的notify_value设置为NO_KEY解决设备第一次上电丢失按键按下事件。 image

2.16 wireless_mic_sdk-v1.4.1_duplex HID按键无法唤醒智能语音助手

1.HID按键最多加16个,需选择一个替换为0XCF(语音唤醒键值)。
image 2.按键调用对应的BIT值,即原本被替换的hid_key。
image 3.语音按键是需要长按的,可以如图增加延时实现。不过不是很建议使用延时的方式实现,改成用户按下就发键值,抬起就发00(也就是延时之后的那个键值),这样兼容性会更好。
image gitlab地址:Files · feature_open_SIRI · 自由品牌 / 客户支持 / SOUNDBOX / wireless_mic / wireless_mic_sdk · GitLab

2.17 USB-Audio-pc声卡模式: 电脑没有开播放器或者开着播放器(没播放过),操作音箱音量加减,获取不到电脑进度条音量值

注释以下
image

示例

  1. usb hid keyboard 和 CONSUMER_PAGE 联合使用 AC695N_soundbox_sdk_release_3.1.2_case_usb_hid_multi_report.zip

本文档包含以下子页面

  • HID配置
  • CDC配置
  • USB描述符相关
  • AC1289A_TYPE-C耳机V1.2
  • PC模式下的HID Report修改说明及解析
  • PC模式下增加Teams唤起功能
  • 701 151SDK,USBDP口复用UART,WIN7电脑不识别处理方法
Prev
MIDI音乐实现
Next
FM相关应用