ai level hid command

This commit is contained in:
Steven Dan
2026-03-27 23:50:03 +08:00
parent 8b56f5cd2d
commit d0e98ea135
5 changed files with 268 additions and 2 deletions

View File

@@ -85,6 +85,9 @@ unsigned g_last_volume_level = 0xFF; // 上次已上报的音量级别0xFF
unsigned g_mic_volume_level = 37; // 麦克风PGA增益级别0=mute, 1-37=0dB~36dBHID可见范围
unsigned g_request_mic_volume_set = 0;
unsigned g_last_mic_volume_level = 0xFF; // 上次已上报的麦克风增益级别0xFF表示初始化未完成
unsigned g_dnr_strength = 100; // AI降噪强度HID值0=关2-100=开步进2100→-200dB最强
unsigned g_last_dnr_strength = 0xFF; // 上次已上报的降噪强度0xFF表示首次未上报触发开机上报
unsigned g_request_dnr_strength_set = 0; // HID 0x85 SET_AI_NOISE_STRENGTH待处理标志
unsigned g_dac_m_gain = 0;
unsigned g_unmute_delay_time = 0;
unsigned g_format_delay_time = 0;
@@ -280,6 +283,7 @@ extern unsigned g_host_os; // 1 -> Windows, 2 -> Others
extern unsigned g_mute_on_off_t0;
extern unsigned g_uac_vol;
extern void dnr_set_mode(unsigned char mode);
extern void dnr_set_strength_level(unsigned char strength);
extern void device_reboot(void);
@@ -376,6 +380,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
unsigned flag_footsteps_enhancement = 2;
// 出厂默认AI降噪开启
unsigned flag_aidenoise_onoff = 1;
unsigned dnr_strength_saved = 100; // AI降噪重新开启时恢复的强度0x85可更新
// Buttons state
unsigned push_button_music_mode_state_old = 1; // Active low
@@ -1264,12 +1269,14 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
if(flag_aidenoise_onoff)
{
led_on(&led_ctx, LED_ANC);
dnr_set_mode(1);
dnr_set_strength_level((unsigned char)dnr_strength_saved);
SET_SHARED_GLOBAL(g_dnr_strength, dnr_strength_saved);
}
else
{
led_off(&led_ctx, LED_ANC);
dnr_set_mode(0);
dnr_set_strength_level(0);
SET_SHARED_GLOBAL(g_dnr_strength, 0);
}
//led_update_all(&led_ctx);
@@ -1652,6 +1659,30 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
}
}
// 处理HID SET_AI_NOISE_STRENGTH (0x85) 请求
#if DNR_ENABLE == 1
{
unsigned dnr_req;
GET_SHARED_GLOBAL(dnr_req, g_request_dnr_strength_set);
if (dnr_req) {
SET_SHARED_GLOBAL(g_request_dnr_strength_set, 0);
unsigned new_strength;
GET_SHARED_GLOBAL(new_strength, g_dnr_strength);
dnr_set_strength_level((unsigned char)new_strength);
if (new_strength == 0) {
flag_aidenoise_onoff = 0;
led_off(&led_ctx, LED_ANC);
} else {
flag_aidenoise_onoff = 1;
dnr_strength_saved = new_strength;
led_on(&led_ctx, LED_ANC);
}
led_update_all(&led_ctx);
debug_printf("HID SET_AI_NOISE_STRENGTH: strength=%d\n", new_strength);
}
}
#endif
#if HID_CONTROLS == 1
// HID监听音量变化主动上报编码器旋转或HID命令导致的音量变化
{
@@ -1698,6 +1729,32 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
}
g_last_mic_volume_level = current_mic_level;
}
// HID AI降噪强度变化主动上报含首次开机上报g_last_dnr_strength初始为0xFF
#if DNR_ENABLE == 1
{
unsigned current_dnr_strength;
GET_SHARED_GLOBAL(current_dnr_strength, g_dnr_strength);
#if HID_DFU_EN
if (!g_in_fw_upgrade)
#endif
if (g_last_dnr_strength != current_dnr_strength) {
unsafe {
unsigned char * unsafe ptr = (unsigned char * unsafe)hidSendData;
ptr[0] = 1;
ptr[1] = 0x77;
ptr[2] = 0x86;
ptr[3] = (unsigned char)current_dnr_strength;
for (int i = 4; i < HID_MAX_DATA_BYTES; i++)
ptr[i] = 0x00;
}
hidSetChangePending(0x1);
debug_printf("DNR strength changed: %d -> %d, HID report sent\n",
g_last_dnr_strength, current_dnr_strength);
}
g_last_dnr_strength = current_dnr_strength;
}
#endif
#endif
#if EQ_EN

View File

@@ -96,6 +96,15 @@ void dnr_set_mode(unsigned char mode)
g_dnr_level = -200;
}
// 按HID强度值0=关2-100步进2设置降噪深度strength * 2 → dB100→-200dB
void dnr_set_strength_level(unsigned char strength)
{
if (strength == 0)
g_dnr_level = 0;
else
g_dnr_level = -(float)(strength * 2);
}
void start_dsp_processing(void)
{
setNoisy_mix_factor(g_dnr_level);

View File

@@ -648,6 +648,27 @@ unsigned char process_send_params(uint8_t data[], uint16_t len) {
return true;
}
// 处理设置AI降噪强度命令 (0x85) - SET_AI_NOISE_STRENGTH
// 有效值: 0(关闭), 2,4,...,100(步进2); 强度映射: strength*2 → dB (100→-200dB)
if (data[1] == 0x85) {
uint8_t strength = data[2];
if (strength > 100 || (strength != 0 && strength % 2 != 0)) {
return false;
}
extern unsigned g_dnr_strength;
extern unsigned g_request_dnr_strength_set;
g_dnr_strength = strength;
g_request_dnr_strength_set = 1;
read_request.pending_cmd = 0x86; // 设置后用0x86格式回报当前强度
return true;
}
// 处理读取AI降噪强度命令 (0x86) - GET_AI_NOISE_STRENGTH
if (data[1] == 0x86) {
read_request.pending_cmd = 0x86;
return true;
}
// 处理设置音量命令 (0x93) - SET_VOLUME
// 范围: 0-15 (0=静音, 1-15=-28dB~0dB, 2dB/步)
if (data[1] == 0x93) {
@@ -1029,6 +1050,17 @@ unsigned char process_read_params(uint8_t response[]) {
read_request.pending_cmd = 0;
return true;
}
// 处理AI降噪强度请求/响应 (0x86) - GET_AI_NOISE_STRENGTH
if (read_request.pending_cmd == 0x86) {
RSP_HDR(response, 0x86);
extern unsigned g_dnr_strength;
response[2] = (uint8_t)g_dnr_strength;
read_request.pending_cmd = 0;
return true;
}
// 处理读取音量请求 (0x94) - GET_VOLUME
if (read_request.pending_cmd == 0x94) {
RSP_HDR(response, 0x94);

View File

@@ -653,6 +653,27 @@ class EQDesigner(QMainWindow):
mic_btn_layout.addWidget(self.get_mic_volume_btn)
volume_layout.addRow(mic_btn_layout)
# AI降噪强度控制
noise_strength_layout = QHBoxLayout()
self.noise_strength_label = QLabel("AI降噪强度 (0x85/0x86):")
self.noise_strength_spin = QSpinBox()
self.noise_strength_spin.setRange(0, 100)
self.noise_strength_spin.setValue(100)
self.noise_strength_spin.setSingleStep(2)
self.noise_strength_spin.setSuffix(" (0=关闭, 2-100=强度, 步进2)")
noise_strength_layout.addWidget(self.noise_strength_label)
noise_strength_layout.addWidget(self.noise_strength_spin)
volume_layout.addRow(noise_strength_layout)
noise_btn_layout = QHBoxLayout()
self.set_noise_strength_btn = QPushButton("设置AI降噪强度")
self.set_noise_strength_btn.clicked.connect(self.on_set_noise_strength)
self.get_noise_strength_btn = QPushButton("读取AI降噪强度")
self.get_noise_strength_btn.clicked.connect(self.on_get_noise_strength)
noise_btn_layout.addWidget(self.set_noise_strength_btn)
noise_btn_layout.addWidget(self.get_noise_strength_btn)
volume_layout.addRow(noise_btn_layout)
# 读取采样率和格式按钮
self.get_sample_format_btn = QPushButton("读取采样率和格式")
self.get_sample_format_btn.clicked.connect(self.on_get_sample_format)
@@ -2404,6 +2425,92 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{
except Exception as e:
log_message(LOG_LEVEL_ERROR, f"读取麦克风增益时出错: {str(e)}", self.log_level)
def on_set_noise_strength(self):
"""设置AI降噪强度发送0x85命令0=关闭2-100偶数=强度步进2"""
if self.device_combo.currentData() is None:
log_message(LOG_LEVEL_ERROR, "请先选择设备", self.log_level)
return
strength = self.noise_strength_spin.value()
# 强制对齐到偶数SpinBox步进2但手动输入可能为奇数
if strength != 0 and strength % 2 != 0:
strength -= 1
self.noise_strength_spin.setValue(strength)
desc = "关闭AI降噪" if strength == 0 else f"强度{strength}(内部{-(strength*2)}dB"
reply = QMessageBox.question(
self,
"确认设置AI降噪强度",
f"将要设置AI降噪强度为: {strength}\n{desc}\n\n是否继续?",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No
)
if reply == QMessageBox.Yes:
try:
device_info = self.device_combo.currentData()
h = hid.device()
h.open(device_info['vendor_id'], device_info['product_id'])
h.set_nonblocking(1)
data = bytearray(63)
data[0] = 0x77
data[1] = 0x85 # SET_AI_NOISE_STRENGTH
data[2] = strength
log_message(LOG_LEVEL_INFO, f"正在设置AI降噪强度为 {strength}...", self.log_level)
h.write([0x01] + list(data))
h.close()
log_message(LOG_LEVEL_INFO, f"AI降噪强度 {strength} 设置成功", self.log_level)
QMessageBox.information(self, "成功", f"AI降噪强度已设置为: {strength}\n{desc}")
except Exception as e:
log_message(LOG_LEVEL_ERROR, f"设置AI降噪强度时出错: {str(e)}", self.log_level)
def on_get_noise_strength(self):
"""读取AI降噪强度发送0x86命令"""
if self.device_combo.currentData() is None:
log_message(LOG_LEVEL_ERROR, "请先选择设备", self.log_level)
return
try:
device_info = self.device_combo.currentData()
h = hid.device()
h.open(device_info['vendor_id'], device_info['product_id'])
h.set_nonblocking(1)
data = bytearray(63)
data[0] = 0x77
data[1] = 0x86 # GET_AI_NOISE_STRENGTH
log_message(LOG_LEVEL_INFO, "正在读取AI降噪强度...", self.log_level)
h.write([0x01] + list(data))
import time
time.sleep(0.05)
reply = h.get_input_report(0x1, 64)
if reply and len(reply) == 64:
if reply[0] == 0x01 and reply[1] == 0x77 and reply[2] == 0x86:
strength = reply[3]
self.noise_strength_spin.setValue(strength)
desc = "关闭" if strength == 0 else f"强度{strength}{-(strength*2)}dB"
log_message(LOG_LEVEL_INFO, f"当前AI降噪强度: {strength}", self.log_level)
QMessageBox.information(
self, "AI降噪强度",
f"当前AI降噪强度: {strength}\n{desc}\n\n"
f"范围: 0=关闭, 2-100偶数=强度级别, 步进2"
)
else:
log_message(LOG_LEVEL_ERROR, f"无效的0x86响应同步头: 0x{reply[1]:02x} 0x{reply[2]:02x}", self.log_level)
else:
log_message(LOG_LEVEL_ERROR, "未收到0x86响应数据", self.log_level)
h.close()
except Exception as e:
log_message(LOG_LEVEL_ERROR, f"读取AI降噪强度时出错: {str(e)}", self.log_level)
def on_get_sample_format(self):
"""读取采样率和格式信息发送0x9F命令"""
if self.device_combo.currentData() is None:

View File

@@ -11,6 +11,8 @@
| 0x82 | SET_MIC_VOLUME | 设置麦克风增益级别 | 主机→设备 | 设置麦克风PGA增益0=静音, 1-37=0dB~36dB, 1dB/步) |
| 0x83 | GET_MIC_VOLUME | 获取麦克风增益级别 | 主机→设备 | 读取当前麦克风PGA增益级别0=静音, 1-37=0dB~36dB |
| 0x84 | FACTORY_RESET | 恢复出厂默认设置 | 主机→设备 | 删除Flash中所有已保存参数设备重启后自动恢复出厂默认值 |
| 0x85 | SET_AI_NOISE_STRENGTH | 设置AI降噪强度 | 主机→设备 | 设置AI降噪强度0=关闭2-100偶数=强度级别步进2100对应最强-200dB |
| 0x86 | GET_AI_NOISE_STRENGTH | 获取AI降噪强度 | 主机→设备 | 读取当前AI降噪强度强度变化含按键切换、开机初始值时设备主动上报 |
| 0x8A | SET_EQ_MODE | 切换EQ模式 | 主机→设备 | 切换EQ模式 |
| 0x8B | GET_EQ_MODE | 获取当前EQ模式信息 | 主机→设备 | 读取设备当前EQ模式和名称 |
| 0x8C | SET_MODE_GAIN_AND_NAME | 设置模式整体增益和名称 | 主机→设备 | 设置模式整体增益和名称 |
@@ -147,6 +149,65 @@
- 重启后所有参数将恢复为出厂默认值
- 此操作不可撤销
### 2.0d 0x85 - SET_AI_NOISE_STRENGTH (设置AI降噪强度)
**功能**: 设置AI降噪强度级别
**方向**: 主机→设备
**数据包格式**:
```
字节位置 | 长度 | 内容 | 描述
---------|------|------|------
0 | 1 | 0x77 | 同步头1
1 | 1 | 0x85 | 命令码
2 | 1 | uint8 | 强度值 (0=关闭, 2/4/.../100=强度级别, 步进2)
3-62 | 60 | 0x00 | 保留字节
```
**参数说明**:
- **强度值范围**: 0、2、4、6、…、100共51个有效值
- **0**: 关闭AI降噪
- **2-100步进2**: 开启AI降噪强度递增内部dB映射`dB = -(strength × 2)`
- 2 → -4 dB最轻微降噪
- 50 → -100 dB
- 100 → -200 dB最强降噪出厂默认
- **奇数或 >100** 为无效值,固件将拒绝(返回无响应)
**设备端处理**:
- 强度=0关闭AI降噪算法熄灭LED_ANCflag_aidenoise_onoff=0
- 强度=2-100开启AI降噪算法点亮LED_ANCflag_aidenoise_onoff=1更新内部降噪深度
- 设置成功后设备主动上报当前强度0x86格式
- **不保存到Flash**重启后AI降噪恢复为开启强度=100即-200dB最强
**返回值**:
无直接返回设置成功后设备通过0x86格式主动上报当前强度值。
### 2.0e 0x86 - GET_AI_NOISE_STRENGTH (获取AI降噪强度)
**功能**: 读取设备当前AI降噪强度强度变化时设备主动上报
**方向**: 主机→设备(请求),设备→主机(响应/主动上报)
**请求数据包格式**:
```
字节位置 | 长度 | 内容 | 描述
---------|------|------|------
0 | 1 | 0x77 | 同步头1
1 | 1 | 0x86 | 命令码
2-62 | 61 | 0x00 | 保留字节
```
**响应数据包格式**(含主动上报):
```
字节位置 | 长度 | 内容 | 描述
---------|------|------|------
0 | 1 | 0x01 | Report ID
1 | 1 | 0x77 | 同步头1
2 | 1 | 0x86 | 同步头2
3 | 1 | uint8 | 当前强度值 (0=关闭, 2-100=强度级别)
4-62 | 59 | 0x00 | 保留字节
```
**主动上报说明**:
- **开机时**:设备初始化完成后主动上报当前强度(出厂默认=100
- **按键切换**用户按下AI降噪按键时设备主动上报新强度关闭时上报0开启时上报恢复的强度
- **HID SET_AI_NOISE_STRENGTH0x85命令成功执行后**,设备主动上报新强度
### 2.1 0x8A - SET_EQ_MODE (切换EQ模式)
**功能**: 切换当前EQ模式
**方向**: 主机→设备