From fb30861ffd73214dd6d4c6d1661cdf056208db53 Mon Sep 17 00:00:00 2001 From: Steven Dan Date: Thu, 26 Mar 2026 10:42:50 +0800 Subject: [PATCH] update mic volume --- .../src/extensions/audiohw.xc | 50 ++++- .../src/extensions/eq.c | 34 +++ .../src/extensions/eq_designer_new.py | 196 +++++++++++++----- .../src/extensions/eq_hid_protocol.md | 59 ++++++ 4 files changed, 281 insertions(+), 58 deletions(-) diff --git a/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/audiohw.xc b/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/audiohw.xc index e5867f5..98acc2a 100644 --- a/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/audiohw.xc +++ b/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/audiohw.xc @@ -84,6 +84,9 @@ unsigned g_host_volume = 0x0; unsigned char g_hid_status_report_data[63] = {0}; unsigned int g_hid_status_report_index = 0; unsigned g_last_volume_level = 0xFF; // 上次已上报的音量级别,0xFF表示初始化未完成 +unsigned g_mic_volume_level = 38; // 麦克风PGA增益级别(1-38,对应NAU88L21寄存器值) +unsigned g_request_mic_volume_set = 0; +unsigned g_last_mic_volume_level = 0xFF; // 上次已上报的麦克风增益级别,0xFF表示初始化未完成 unsigned g_dac_m_gain = 0; unsigned g_unmute_delay_time = 0; unsigned g_format_delay_time = 0; @@ -493,8 +496,9 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol) else save_value(dac_vol_path, (unsigned char)dac_level); } - // 同步全局音量变量与从Flash恢复的dac_level + // 同步全局音量变量与从Flash恢复的dac_level / codec_adc_pga_gain_reg_value g_volume_level = dac_level; + g_mic_volume_level = codec_adc_pga_gain_reg_value; // ADCL PGA default setting mic_volume(codec_adc_pga_gain_reg_value); // make sure to write adc reg after initialize the codec, otherwise it does not take effect because of the hardware reset in the initial code @@ -960,6 +964,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol) // 增加音量 mic_volume(++codec_adc_pga_gain_reg_value); + g_mic_volume_level = codec_adc_pga_gain_reg_value; debug_printf("volume up %d\n", codec_adc_pga_gain_reg_value); save_value(mic_vol_path, codec_adc_pga_gain_reg_value); uint8_t new_led_count = mic_gain_to_led[codec_adc_pga_gain_reg_value]; @@ -977,6 +982,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol) // 减小音量 mic_volume(--codec_adc_pga_gain_reg_value); + g_mic_volume_level = codec_adc_pga_gain_reg_value; debug_printf("volume down %d\n", codec_adc_pga_gain_reg_value); save_value(mic_vol_path, codec_adc_pga_gain_reg_value); @@ -1261,8 +1267,31 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol) } } + // 处理HID SET_MIC_VOLUME (0x82) 请求:应用新麦克风增益到硬件和LED + if (g_request_mic_volume_set) { + g_request_mic_volume_set = 0; + unsigned new_mic_level = g_mic_volume_level; + if (new_mic_level >= NAU88L21_PGA_GAIN_REG_MIN_USED_VALUE && + new_mic_level <= NAU88L21_PGA_GAIN_REG_MAX_VALUE) { + uint8_t new_led_count; + codec_adc_pga_gain_reg_value = new_mic_level; + mic_volume(codec_adc_pga_gain_reg_value); + save_value(mic_vol_path, (unsigned char)codec_adc_pga_gain_reg_value); + // 更新麦克风增益指示LED + new_led_count = mic_gain_to_led[codec_adc_pga_gain_reg_value]; + for (int i = 0; i < 15; i++) { + if (i < new_led_count) + led_on(&led_ctx, led_l_physical_map[i]); + else + led_off(&led_ctx, led_l_physical_map[i]); + } + led_update_all(&led_ctx); + debug_printf("HID SET_MIC_VOLUME: pga=%d\n", codec_adc_pga_gain_reg_value); + } + } + #if HID_CONTROLS == 1 - // HID音量变化主动上报(编码器旋转或HID命令导致的音量变化) + // HID监听音量变化主动上报(编码器旋转或HID命令导致的音量变化) { unsigned current_volume_level = g_volume_level; if (g_last_volume_level != current_volume_level && g_last_volume_level != 0xFF) { @@ -1278,6 +1307,23 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol) } g_last_volume_level = current_volume_level; } + + // HID麦克风增益变化主动上报 + { + unsigned current_mic_level = g_mic_volume_level; + if (g_last_mic_volume_level != current_mic_level && g_last_mic_volume_level != 0xFF) { + g_hid_status_report_data[0] = 0x77; // 同步头1 + g_hid_status_report_data[1] = 0x83; // GET_MIC_VOLUME命令码 + g_hid_status_report_data[2] = (unsigned char)current_mic_level; + for (int i = 3; i < 63; i++) + g_hid_status_report_data[i] = 0x00; + g_hid_status_report_index = 63; + hidSetChangePending(0x1); + debug_printf("Mic volume changed: %d -> %d, HID report sent\n", + g_last_mic_volume_level, current_mic_level); + } + g_last_mic_volume_level = current_mic_level; + } #endif #if EQ_EN diff --git a/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/eq.c b/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/eq.c index 9d58753..d223908 100644 --- a/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/eq.c +++ b/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/eq.c @@ -606,6 +606,30 @@ unsigned char process_send_params(uint8_t data[], uint16_t len) { return true; } + // 处理设置麦克风增益命令 (0x82) - SET_MIC_VOLUME + // 范围: 1-38 (NAU88L21 PGA寄存器值,1=0dB, 38≈36+1.5dB) + if (data[1] == 0x82) { + uint8_t mic_level = data[2]; + + // 参数验证: 1-38 + if (mic_level < 1 || mic_level > 38) { + return false; + } + + extern unsigned g_mic_volume_level; + extern unsigned g_request_mic_volume_set; + g_mic_volume_level = mic_level; + g_request_mic_volume_set = 1; + + return true; + } + + // 处理读取麦克风增益命令 (0x83) - GET_MIC_VOLUME + if (data[1] == 0x83) { + read_request.pending_cmd = 0x83; + return true; + } + // 处理设置音量命令 (0x93) - SET_VOLUME // 范围: 0-15 (0=静音, 1-15=-28dB~0dB, 2dB/步) if (data[1] == 0x93) { @@ -940,6 +964,16 @@ unsigned char process_read_params(uint8_t response[]) { read_request.pending_cmd = 0; // Clear read request flag return true; } + // 处理读取麦克风增益请求 (0x83) - GET_MIC_VOLUME + if (read_request.pending_cmd == 0x83) { + RSP_HDR(response, 0x83); + + extern unsigned g_mic_volume_level; + response[2] = (uint8_t)g_mic_volume_level; + + read_request.pending_cmd = 0; + return true; + } // 处理读取音量请求 (0x94) - GET_VOLUME if (read_request.pending_cmd == 0x94) { RSP_HDR(response, 0x94); diff --git a/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/eq_designer_new.py b/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/eq_designer_new.py index 31bbda3..7e70298 100644 --- a/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/eq_designer_new.py +++ b/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/eq_designer_new.py @@ -597,26 +597,47 @@ class EQDesigner(QMainWindow): self.ui_groups['volume'] = volume_group # 保存引用 volume_layout = QFormLayout(volume_group) - # 音量级别显示和设置 + # 监听音量(DAC/耳机)级别显示和设置 volume_control_layout = QHBoxLayout() - self.volume_label = QLabel("音量级别:") + self.volume_label = QLabel("监听音量 (0x93/0x94):") self.volume_spin = QSpinBox() - self.volume_spin.setRange(0, 60) - self.volume_spin.setValue(60) - self.volume_spin.setSuffix(" (0=最小, 60=最大)") + self.volume_spin.setRange(0, 15) + self.volume_spin.setValue(15) + self.volume_spin.setSuffix(" (0=静音, 15=0dB)") volume_control_layout.addWidget(self.volume_label) volume_control_layout.addWidget(self.volume_spin) volume_layout.addRow(volume_control_layout) - # 设置音量按钮 - self.set_volume_btn = QPushButton("设置音量") + # 设置监听音量按钮 + vol_btn_layout = QHBoxLayout() + self.set_volume_btn = QPushButton("设置监听音量") self.set_volume_btn.clicked.connect(self.on_set_volume) - volume_layout.addRow(self.set_volume_btn) - - # 读取音量按钮 - self.get_volume_btn = QPushButton("读取音量") + self.get_volume_btn = QPushButton("读取监听音量") self.get_volume_btn.clicked.connect(self.on_get_volume) - volume_layout.addRow(self.get_volume_btn) + vol_btn_layout.addWidget(self.set_volume_btn) + vol_btn_layout.addWidget(self.get_volume_btn) + volume_layout.addRow(vol_btn_layout) + + # 麦克风增益级别显示和设置 + mic_vol_control_layout = QHBoxLayout() + self.mic_volume_label = QLabel("麦克风增益 (0x82/0x83):") + self.mic_volume_spin = QSpinBox() + self.mic_volume_spin.setRange(1, 38) + self.mic_volume_spin.setValue(38) + self.mic_volume_spin.setSuffix(" (1=0dB, 38=最大)") + mic_vol_control_layout.addWidget(self.mic_volume_label) + mic_vol_control_layout.addWidget(self.mic_volume_spin) + volume_layout.addRow(mic_vol_control_layout) + + # 设置/读取麦克风增益按钮 + mic_btn_layout = QHBoxLayout() + self.set_mic_volume_btn = QPushButton("设置麦克风增益") + self.set_mic_volume_btn.clicked.connect(self.on_set_mic_volume) + self.get_mic_volume_btn = QPushButton("读取麦克风增益") + self.get_mic_volume_btn.clicked.connect(self.on_get_mic_volume) + mic_btn_layout.addWidget(self.set_mic_volume_btn) + mic_btn_layout.addWidget(self.get_mic_volume_btn) + volume_layout.addRow(mic_btn_layout) # 读取采样率和格式按钮 self.get_sample_format_btn = QPushButton("读取采样率和格式") @@ -2295,20 +2316,18 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{ log_message(LOG_LEVEL_ERROR, f"设置并保存EQ模式时出错: {str(e)}", self.log_level) def on_set_volume(self): - """设置音量级别(发送0x93命令)""" + """设置监听音量级别(发送0x93命令,范围0-15)""" if self.device_combo.currentData() is None: log_message(LOG_LEVEL_ERROR, "请先选择设备", self.log_level) return - # 获取音量值 volume_level = self.volume_spin.value() - # 弹出确认对话框 reply = QMessageBox.question( self, - "确认设置音量", - f"将要设置音量级别为: {volume_level}\n\n" - f"音量范围: 0-60 (0=最小音量, 60=最大音量)\n\n" + "确认设置监听音量", + f"将要设置监听音量级别为: {volume_level}\n\n" + f"音量范围: 0-15 (0=静音, 1=-28dB, ..., 15=0dB)\n\n" f"是否继续?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No @@ -2321,30 +2340,23 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{ h.open(device_info['vendor_id'], device_info['product_id']) h.set_nonblocking(1) - # 构建0x93数据包 - data = bytearray(63) # 63字节数据包 - data[0] = 0x77 # 同步头1 - data[1] = 0x93 # 命令码 (SET_VOLUME) - data[2] = volume_level # 音量级别 (0-60) - # 其余字节保持为0 + data = bytearray(63) + data[0] = 0x77 + data[1] = 0x93 # SET_VOLUME + data[2] = volume_level # 0-15 - # 发送请求 - log_message(LOG_LEVEL_INFO, f"正在设置音量级别为 {volume_level}...", self.log_level) + log_message(LOG_LEVEL_INFO, f"正在设置监听音量级别为 {volume_level}...", self.log_level) h.write([0x01] + list(data)) - h.close() - log_message(LOG_LEVEL_INFO, f"音量级别 {volume_level} 设置成功", self.log_level) - QMessageBox.information( - self, - "成功", - f"音量级别已设置为: {volume_level}" - ) + + log_message(LOG_LEVEL_INFO, f"监听音量级别 {volume_level} 设置成功", self.log_level) + QMessageBox.information(self, "成功", f"监听音量级别已设置为: {volume_level}") except Exception as e: - log_message(LOG_LEVEL_ERROR, f"设置音量时出错: {str(e)}", self.log_level) + log_message(LOG_LEVEL_ERROR, f"设置监听音量时出错: {str(e)}", self.log_level) def on_get_volume(self): - """读取音量级别(发送0x94命令)""" + """读取监听音量级别(发送0x94命令)""" if self.device_combo.currentData() is None: log_message(LOG_LEVEL_ERROR, "请先选择设备", self.log_level) return @@ -2355,35 +2367,25 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{ h.open(device_info['vendor_id'], device_info['product_id']) h.set_nonblocking(1) - # 构建0x94数据包 - data = bytearray(63) # 63字节数据包 - data[0] = 0x77 # 同步头1 - data[1] = 0x94 # 命令码 (GET_VOLUME) - # 其余字节保持为0 + data = bytearray(63) + data[0] = 0x77 + data[1] = 0x94 # GET_VOLUME - # 发送请求 - log_message(LOG_LEVEL_INFO, "正在读取音量级别...", self.log_level) + log_message(LOG_LEVEL_INFO, "正在读取监听音量级别...", self.log_level) h.write([0x01] + list(data)) - # 读取响应 import time - time.sleep(0.05) # 等待设备响应 - reply = h.get_input_report(0x1, 64) # 64字节响应 + time.sleep(0.05) + reply = h.get_input_report(0x1, 64) if reply and len(reply) == 64: - # 检查Report ID和同步头 if reply[0] == 0x01 and reply[1] == 0x77 and reply[2] == 0x94: - # 解析音量级别 volume_level = reply[3] - - # 更新UI显示 self.volume_spin.setValue(volume_level) - - log_message(LOG_LEVEL_INFO, f"当前音量级别: {volume_level}", self.log_level) + log_message(LOG_LEVEL_INFO, f"当前监听音量级别: {volume_level}", self.log_level) QMessageBox.information( - self, - "音量级别", - f"当前音量级别: {volume_level}\n\n" - f"音量范围: 0-60 (0=最小音量, 60=最大音量)" + self, "监听音量级别", + f"当前监听音量级别: {volume_level}\n\n" + f"音量范围: 0-15 (0=静音, 1=-28dB, ..., 15=0dB)" ) else: log_message(LOG_LEVEL_ERROR, f"无效的0x94响应同步头: 0x{reply[1]:02x} 0x{reply[2]:02x}", self.log_level) @@ -2393,7 +2395,89 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{ h.close() except Exception as e: - log_message(LOG_LEVEL_ERROR, f"读取音量时出错: {str(e)}", self.log_level) + log_message(LOG_LEVEL_ERROR, f"读取监听音量时出错: {str(e)}", self.log_level) + + def on_set_mic_volume(self): + """设置麦克风增益级别(发送0x82命令,范围1-38)""" + if self.device_combo.currentData() is None: + log_message(LOG_LEVEL_ERROR, "请先选择设备", self.log_level) + return + + mic_level = self.mic_volume_spin.value() + + reply = QMessageBox.question( + self, + "确认设置麦克风增益", + f"将要设置麦克风增益级别为: {mic_level}\n\n" + f"增益范围: 1-38 (1=0dB, 38≈36+1.5dB)\n\n" + f"是否继续?", + 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] = 0x82 # SET_MIC_VOLUME + data[2] = mic_level # 1-38 + + log_message(LOG_LEVEL_INFO, f"正在设置麦克风增益级别为 {mic_level}...", self.log_level) + h.write([0x01] + list(data)) + h.close() + + log_message(LOG_LEVEL_INFO, f"麦克风增益级别 {mic_level} 设置成功", self.log_level) + QMessageBox.information(self, "成功", f"麦克风增益级别已设置为: {mic_level}") + + except Exception as e: + log_message(LOG_LEVEL_ERROR, f"设置麦克风增益时出错: {str(e)}", self.log_level) + + def on_get_mic_volume(self): + """读取麦克风增益级别(发送0x83命令)""" + 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] = 0x83 # GET_MIC_VOLUME + + log_message(LOG_LEVEL_INFO, "正在读取麦克风增益级别...", 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] == 0x83: + mic_level = reply[3] + self.mic_volume_spin.setValue(mic_level) + log_message(LOG_LEVEL_INFO, f"当前麦克风增益级别: {mic_level}", self.log_level) + QMessageBox.information( + self, "麦克风增益级别", + f"当前麦克风增益级别: {mic_level}\n\n" + f"增益范围: 1-38 (1=0dB, 38≈36+1.5dB)" + ) + else: + log_message(LOG_LEVEL_ERROR, f"无效的0x83响应同步头: 0x{reply[1]:02x} 0x{reply[2]:02x}", self.log_level) + else: + log_message(LOG_LEVEL_ERROR, "未收到0x83响应数据", self.log_level) + + h.close() + + except Exception as e: + log_message(LOG_LEVEL_ERROR, f"读取麦克风增益时出错: {str(e)}", self.log_level) def on_get_sample_format(self): """读取采样率和格式信息(发送0x9F命令)""" diff --git a/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/eq_hid_protocol.md b/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/eq_hid_protocol.md index e686132..ec91b1c 100644 --- a/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/eq_hid_protocol.md +++ b/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/eq_hid_protocol.md @@ -8,6 +8,8 @@ ### 1.2 支持的指令列表 | 指令码 | 命令名称 | 功能 | 方向 | 描述 | |--------|----------|------|------|------| +| 0x82 | SET_MIC_VOLUME | 设置麦克风增益级别 | 主机→设备 | 设置麦克风PGA增益(1-38:1=0dB, 38=约36+1.5dB) | +| 0x83 | GET_MIC_VOLUME | 获取麦克风增益级别 | 主机→设备 | 读取当前麦克风PGA增益级别(1-38) | | 0x8A | SET_EQ_MODE | 切换EQ模式 | 主机→设备 | 切换EQ模式 | | 0x8B | GET_EQ_MODE | 获取当前EQ模式信息 | 主机→设备 | 读取设备当前EQ模式和名称 | | 0x8C | SET_MODE_GAIN_AND_NAME | 设置模式整体增益和名称 | 主机→设备 | 设置模式整体增益和名称 | @@ -36,6 +38,63 @@ ## 2. 详细指令说明 +### 2.0 0x82 - SET_MIC_VOLUME (设置麦克风增益级别) +**功能**: 设置麦克风PGA增益级别 +**方向**: 主机→设备 +**数据包格式**: +``` +字节位置 | 长度 | 内容 | 描述 +---------|------|------|------ +0 | 1 | 0x77 | 同步头1 +1 | 1 | 0x82 | 命令码 +2 | 1 | uint8 | 增益级别 (1-38: 1=0dB, 38≈36+1.5dB,每级约1dB步进) +3-62 | 60 | 0x00 | 保留字节 +``` + +**参数说明**: +- **增益级别范围:** 1-38(共38级) +- **对应硬件**:NAU88C22 ADC PGA增益寄存器(reg 0x007E),直接写入寄存器值 + - 1:最小增益(0dB) + - 38:最大增益(约36+1.5dB数字增益) + - 中间各级约1dB步进 +- 0 和 >38 均为无效值,固件将拒绝设置 + +**设备端处理**: +- 设置后立即应用到ADC PGA硬件 +- 同步更新前面板LED(L系列15个LED,反映当前增益级别) +- 保存到Flash(mic_vol路径),断电重启后自动恢复 +- 设备端增益变化(含编码器旋转)会主动通过0x83格式上报 + +**返回值**: +无直接返回值。设备端增益变化会主动上报0x83格式数据包。 + +### 2.0b 0x83 - GET_MIC_VOLUME (获取麦克风增益级别) +**功能**: 读取设备当前麦克风PGA增益级别;设备端增益变化时也会主动上报 +**方向**: 主机→设备(请求),设备→主机(响应/主动上报) +**请求数据包格式**: +``` +字节位置 | 长度 | 内容 | 描述 +---------|------|------|------ +0 | 1 | 0x77 | 同步头1 +1 | 1 | 0x83 | 命令码 +2-62 | 61 | 0x00 | 保留字节 +``` + +**响应数据包格式**(含主动上报): +``` +字节位置 | 长度 | 内容 | 描述 +---------|------|------|------ +0 | 1 | 0x01 | Report ID +1 | 1 | 0x77 | 同步头1 +2 | 1 | 0x83 | 同步头2 +3 | 1 | uint8 | 当前增益级别 (1-38) +4-62 | 59 | 0x00 | 保留字节 +``` + +**主动上报说明**: +- 编码器旋转导致增益变化时,设备主动向主机上报当前增益 +- HID SET_MIC_VOLUME(0x82)命令成功执行后,设备也主动上报新增益 + ### 2.1 0x8A - SET_EQ_MODE (切换EQ模式) **功能**: 切换当前EQ模式 **方向**: 主机→设备