From 961615b0f0c655686dc1cba533541be3ed485be0 Mon Sep 17 00:00:00 2001 From: Steven Dan Date: Sat, 11 Apr 2026 11:46:44 +0800 Subject: [PATCH] mute headphone when mic insertion --- .../src/extensions/audiohw.xc | 83 ++++++++++++++----- 1 file changed, 63 insertions(+), 20 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 192dc31..d28e3cf 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 @@ -108,8 +108,10 @@ unsigned g_new_dac_mode = 0; unsigned g_samfreq = 48000; unsigned g_dsd_mode = 0; // mic detect events: mute_handler (tile[1]) → button_task (tile[0]) -#define MIC_DET_MUTE 1 // mic插入或全拔出,立即mute -#define MIC_DET_UNMUTE 2 // 插入1s后恢复音量 +#define MIC_DET_MUTE 1 // mic插入或全拔出,立即mute mic +#define MIC_DET_UNMUTE 2 // 插入1s后恢复mic音量 +#define MIC_DET_DAC_MUTE 3 // mic插入时mute DAC防pop +#define MIC_DET_DAC_UNMUTE 4 // 1s后恢复DAC音量 unsafe chanend uc_audiohw; // tile[1] end: AudioHwConfig → button_task (tile[0]) #if HID_DFU_EN @@ -403,6 +405,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, unsigned flag_mic_mute = 0; unsigned flag_hp_mute = 0; unsigned mic_det_muted = 0; // mic检测导致的mute(不影响LED和g_mic_volume_level) + unsigned dac_det_muted = 0; // mic插入时临时mute DAC防pop(不影响LED) unsigned push_button_mic_mute_state_old = 1; // Active low unsigned push_button_hp_mute_state_old = 1; // Active low @@ -989,6 +992,18 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, mic_volume(codec_adc_pga_gain_reg_value); debug_printf("mic_det: unmute -> pga=%d\n", codec_adc_pga_gain_reg_value); } + } else if (mic_det_cmd == MIC_DET_DAC_MUTE) { + dac_det_muted = 1; + // mute DAC硬件,不改变dac_level/g_volume_level和LED + unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); } + debug_printf("mic_det: dac mute\n"); + } else if (mic_det_cmd == MIC_DET_DAC_UNMUTE) { + dac_det_muted = 0; + // 恢复DAC音量,但如果用户手动hp_mute或dac_level==0则不恢复 + if (!flag_hp_mute && dac_level > DAC_LEVEL_MIN) { + dac_volume(dac_level - DAC_LEVEL_MAX); + debug_printf("mic_det: dac unmute -> level=%d\n", dac_level); + } } break; } @@ -1646,7 +1661,8 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, // 增加音量 ++dac_level; g_volume_level = dac_level; - dac_volume(dac_level - DAC_LEVEL_MAX); + if (!dac_det_muted) + dac_volume(dac_level - DAC_LEVEL_MAX); save_value(dac_vol_path, dac_level); uint8_t new_led_count = dac_gain_to_led[dac_level]; @@ -1665,10 +1681,12 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, // 减小音量 --dac_level; g_volume_level = dac_level; - if(dac_level == DAC_LEVEL_MIN) - unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); } - else - dac_volume(dac_level - DAC_LEVEL_MAX); + if (!dac_det_muted) { + if(dac_level == DAC_LEVEL_MIN) + unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); } + else + dac_volume(dac_level - DAC_LEVEL_MAX); + } save_value(dac_vol_path, dac_level); uint8_t new_led_count = dac_gain_to_led[dac_level]; @@ -1740,10 +1758,12 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, } else { - if(dac_level == DAC_LEVEL_MIN) - unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); } - else - dac_volume(dac_level - DAC_LEVEL_MAX); + if (!dac_det_muted) { + if(dac_level == DAC_LEVEL_MIN) + unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); } + else + dac_volume(dac_level - DAC_LEVEL_MAX); + } g_volume_level = dac_level; hp_mute_blink_tick = 0; for(int i = 0; i < 15; i++) @@ -1796,10 +1816,12 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, if (new_level <= DAC_LEVEL_MAX) { uint8_t new_led_count; dac_level = new_level; - if (dac_level == DAC_LEVEL_MIN) - unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); } - else - dac_volume(dac_level - DAC_LEVEL_MAX); + if (!dac_det_muted) { + if (dac_level == DAC_LEVEL_MIN) + unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); } + else + dac_volume(dac_level - DAC_LEVEL_MAX); + } save_value(dac_vol_path, (unsigned char)dac_level); // 更新DAC音量指示LED new_led_count = dac_gain_to_led[dac_level]; @@ -2102,6 +2124,8 @@ void mute_handler(chanend c_mic_det) unsigned mic1_in = (det_val >> 1) & 1; // bit1: 1=inserted unsigned mic2_in = ((det_val >> 2) & 1) ^ 1; // bit2: 0=inserted, invert unsigned any_mic_in = mic1_in || mic2_in; + unsigned prev_mic1_in = mic1_in; + unsigned prev_mic2_in = mic2_in; unsigned prev_any_mic_in = any_mic_in; // 如果开机时全拔出,发送mute @@ -2126,10 +2150,22 @@ void mute_handler(chanend c_mic_det) mic2_in = ((det_val >> 2) & 1) ^ 1; any_mic_in = mic1_in || mic2_in; - if (any_mic_in != prev_any_mic_in) { - // 状态变化:立即mute防止pop音 + // 检测单个mic插入事件(从拔出变为插入) + unsigned mic1_inserted = (mic1_in && !prev_mic1_in); + unsigned mic2_inserted = (mic2_in && !prev_mic2_in); + unsigned any_inserted = mic1_inserted || mic2_inserted; + unsigned state_changed = (any_mic_in != prev_any_mic_in) || any_inserted; + + if (state_changed) { + // 状态变化:立即mute mic防止pop音 c_mic_det <: (unsigned)MIC_DET_MUTE; - debug_printf("mic det change: mic1=%d mic2=%d -> mute\n", mic1_in, mic2_in); + + // 如果有mic插入,同时mute DAC防pop + if (any_inserted) { + c_mic_det <: (unsigned)MIC_DET_DAC_MUTE; + } + + debug_printf("mic det change: mic1=%d mic2=%d inserted=%d -> mute\n", mic1_in, mic2_in, any_inserted); // 等1s让插拔稳定 delay_milliseconds(1000); @@ -2140,13 +2176,20 @@ void mute_handler(chanend c_mic_det) mic2_in = ((det_val >> 2) & 1) ^ 1; any_mic_in = mic1_in || mic2_in; + // 恢复DAC(插入时的临时mute已满1s) + if (any_inserted) { + c_mic_det <: (unsigned)MIC_DET_DAC_UNMUTE; + } + if (any_mic_in) { - // 有mic插入,恢复音量 + // 有mic插入,恢复mic音量 c_mic_det <: (unsigned)MIC_DET_UNMUTE; debug_printf("mic stable inserted -> unmute\n"); } - // 全拔出则保持mute,不发UNMUTE + // 全拔出则保持mic mute,不发UNMUTE + prev_mic1_in = mic1_in; + prev_mic2_in = mic2_in; prev_any_mic_in = any_mic_in; // 重新同步timer