diff --git a/APP/app_adc.c b/APP/app_adc.c index a8fecd5..0b95062 100644 --- a/APP/app_adc.c +++ b/APP/app_adc.c @@ -303,6 +303,14 @@ void app_adc_sync_volume(uint16_t val) app_adc_volume_map_level(val); } +/* 取当前主音量(复用扫描任务维护的最近一次有效值)。 + * 模拟开关同一时刻只选中一路,离开扫描上下文直接重读 ADC 会串到 + * 其它通道,故统一走 vol_last;未初始化(0xFFFF)时按静音兜底 */ +uint8_t app_adc_get_volume(void) +{ + return (vol_last > 127) ? 0 : (uint8_t)vol_last; +} + static void app_adc_volume_process(void) { uint16_t val = ADC_ReadChannel(ADC_CHANNEL_1)>>5; diff --git a/APP/app_adc.h b/APP/app_adc.h index e0f0c0e..9e67e8e 100644 --- a/APP/app_adc.h +++ b/APP/app_adc.h @@ -27,4 +27,6 @@ void app_adc_in1_scan_part(uint8_t channel); bool app_adc_usb_is_plugged(void); /* /ͬ vol_last levelɨ󴥷 */ void app_adc_sync_volume(uint16_t val); +/* ȡǰ0~127 MasterVolume_Reapply طʹ */ +uint8_t app_adc_get_volume(void); #endif \ No newline at end of file diff --git a/Global/Global.c b/Global/Global.c index 9a113c1..a7017c5 100644 --- a/Global/Global.c +++ b/Global/Global.c @@ -460,6 +460,16 @@ void Send_volume(uint8_t vol) SendMidiDataToDreamDSP(mMasterSysExVolume,12); } +/* 重发当前主音量:开机补发 / 进模式主页 / 开始播放前调用。 + * Dream 上电早期可能丢 SysEx,丢失后旋钮不动就不再重发, + * 会出现"图标低音量、实际音量大";在关键时机重发可自愈 */ +void MasterVolume_Reapply(void) +{ + uint8_t vol = app_adc_get_volume(); + app_adc_sync_volume(vol); /* 兜底刷新 level,保证图标与下发值一致 */ + Send_volume(vol); +} + void Accomp_UpdatePlayingChord(void) { uint8_t midi_note_buff[4] = {0,}; @@ -494,6 +504,8 @@ void ADC_IN1_KEY_Handle(uint8_t key,bool on) case 1: AutoBandTop1_Postamble(0); break; case 2: AutoBandTop1_Postamble(1); break; } + /* 前奏/尾奏起奏前补发主音量,保证与图标一致 */ + MasterVolume_Reapply(); //AutoBandTop1_Start(); AutoBandTop1_SyncStart(); wk_delay_ms(50); @@ -761,6 +773,10 @@ void Pick_Handle() note_cnt = GetChordNotesByType(chord_id, chord_type_index_map[chord_id].type, midi_note_buff); Return_Light_buff(KEY_ID_1629); + /* 首次起奏前补发主音量:防开机 SysEx 丢失后"图标低、实际大" */ + if (StartFlag == 0) + MasterVolume_Reapply(); + switch(mGuiData[GUI_TAB_INDEX].Current) { case 3: diff --git a/Global/Global.h b/Global/Global.h index 66e9c75..7633200 100644 --- a/Global/Global.h +++ b/Global/Global.h @@ -213,6 +213,7 @@ uint8_t GUI_Item_AjustValue(GUI_SWITCH * Group, int8_t Dir); void GUI_Item_AjustLoopValue(GUI_SWITCH * Group, int8_t Dir); void Send_volume(uint8_t vol); +void MasterVolume_Reapply(void); void ADC_IN1_KEY_Handle(uint8_t key,bool on); void TM1617_Handle(uint8_t key); diff --git a/UI/UI_Idle.c b/UI/UI_Idle.c index c048154..d5ce4e2 100644 --- a/UI/UI_Idle.c +++ b/UI/UI_Idle.c @@ -163,11 +163,11 @@ void IdleProcess(DisplayTaskMessage_Type msg) TM1629D_UpdateDisplay(0); StartTouchTask(); StartScanTask(); - /* Dream 上电稍后可能忽略首包 SysEx:再发主音量 + 调音台(保持关机前设置) */ + /* Dream 上电稍后可能忽略首包 SysEx:再发主音量 + 调音台(保持关机前设置)。 + * 此时扫描任务已启动、模拟开关在轮询,不可现场重读 ADC(会串通道), + * 统一用 MasterVolume_Reapply 取扫描任务维护的最近一次有效音量 */ rt_thread_mdelay(400); - vol = ADC_ReadChannel(ADC_CHANNEL_1)>>5; - app_adc_sync_volume(vol); - Send_volume(vol); + MasterVolume_Reapply(); LoadConfig(); Draw_Volume_Bar(UI0902_VOL_X, UI0902_VOL_Y, level, 1, WHITE, GRAY); break; diff --git a/UI/UI_SongMode.c b/UI/UI_SongMode.c index c17efb4..d474677 100644 --- a/UI/UI_SongMode.c +++ b/UI/UI_SongMode.c @@ -242,7 +242,9 @@ void Touch_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex,uint8_t value) mGuiData[ID].Current = value; AutoBandTop1_SetRunVar(mGuiData[ID].Current); }else - { + { + /* 触摸起奏前补发主音量,保证实际音量与图标一致 */ + MasterVolume_Reapply(); AutoBandTop1_FillinWithIndex(value); AutoBandTop1_Start(); } diff --git a/UI/UI_SystemSet.c b/UI/UI_SystemSet.c index dd06276..c7a89b8 100644 --- a/UI/UI_SystemSet.c +++ b/UI/UI_SystemSet.c @@ -124,6 +124,11 @@ void UI_SystemSet_Process(DisplayTaskMessage_Type msg) label_top(); break; + case MSG_ID_EC_VOL: + /* 主音量已在 MainTask 下发;此处只刷新状态栏音量条,保证与旋钮一致 */ + Draw_Volume_Bar(UI0902_VOL_X, UI0902_VOL_Y, msg.HiByte, 1, WHITE, GRAY); + break; + default: break; } diff --git a/UI/UI_global.c b/UI/UI_global.c index 59df327..a2daf93 100644 --- a/UI/UI_global.c +++ b/UI/UI_global.c @@ -54,6 +54,7 @@ void CallUI_Idle(void) { void CallUI_SongMode(void) { app_touch_suppress(500); + MasterVolume_Reapply(); /* 进模式补发主音量,防开机 SysEx 丢失后实际音量与图标不符 */ UI_SongMode_Init(); CurrUIProcress = UI_SongMode_Process; app_log_set_ui_page("Song"); @@ -62,8 +63,9 @@ void CallUI_SongMode(void) { void CallUI_ExpertMode(void) { app_touch_suppress(500); + MasterVolume_Reapply(); UI_ExpertMode_Init(); -// CurrUIProcress = UI_ExpertMode_Process; +// CurrUIProcress = UI_ExpertMode_Process; CurrUIProcress = UI_SongMode_Process; app_log_set_ui_page("Expert"); LOG_I("UI", "page ExpertMode"); @@ -71,8 +73,9 @@ void CallUI_ExpertMode(void) { void CallUI_FreeMode(void) { app_touch_suppress(500); + MasterVolume_Reapply(); UI_FreeMode_Init(); -// CurrUIProcress = UI_FreeMode_Process; +// CurrUIProcress = UI_FreeMode_Process; CurrUIProcress = UI_SongMode_Process; app_log_set_ui_page("Free"); LOG_I("UI", "page FreeMode");