From 67a5fe5d6017d308e4970cbaad4b176f1352abfb Mon Sep 17 00:00:00 2001 From: yuquanjun Date: Thu, 24 Sep 2026 20:08:27 +0800 Subject: [PATCH] fix(band): revert soft-stop; ignore round/side keys on mode select Restore hard AutoBandTop1_Stop and drop eaten-start/followup tick-gate. Keep API stubs for callers. Block TM1617 round keys and reinforce side-key/BLE gates while InModeFlag is false. Co-authored-by: Cursor --- APP/app_tm1617.c | 4 +- Global/Global.c | 134 +++++++++-------------------------------------- Global/Global.h | 20 +++---- task/task_init.c | 26 ++++----- 4 files changed, 49 insertions(+), 135 deletions(-) diff --git a/APP/app_tm1617.c b/APP/app_tm1617.c index 75c0c5d..f11e65a 100644 --- a/APP/app_tm1617.c +++ b/APP/app_tm1617.c @@ -79,7 +79,9 @@ uint8_t app_tm1617_scan_key(void) { key_last = key; LOG_I("KEY", "tm1617 key=%u", (unsigned)key); - TM1617_Handle(key); + /* ????????????????/?????? */ + if (InModeFlag) + TM1617_Handle(key); return key; } return KEY_NULL; diff --git a/Global/Global.c b/Global/Global.c index 97fa91d..e93463f 100644 --- a/Global/Global.c +++ b/Global/Global.c @@ -119,7 +119,7 @@ static void Band_StartLocalRetry(uint8_t midi, uint8_t *notes, uint8_t n); static void Band_StartPieceRetry(uint8_t *notes, uint8_t n); static void Band_SyncStartRetry(void); static void Band_StopBeforeColdStart(void); -/* 1=喂 AutoBand 1ms 节拍;停止键软停时清 0,避免库继续出音且不必 Stop */ +/* 1=喂 AutoBand 1ms 节拍(软停曾清 0;已回退硬停,保持为 1) */ uint8_t Band_TickGate = 1; uint8_t AutoCloseTime = 15; @@ -795,10 +795,7 @@ static void Univ_StartWithPreamble(uint8_t *notes, uint8_t n) mGuiData[GUI_PLAY_SECTION].Current = 0; /* 段落后续固定进段落1 */ if (session_was_on) - { - Band_MarkRealStop(); AutoBandTop1_Stop(); - } else Band_StopBeforeColdStart(); @@ -971,6 +968,9 @@ void ADC_IN1_KEY_Handle(uint8_t key,bool on) void TM1617_Handle(uint8_t key) { + /* 模式选择页:圆形段落键不得假触摸点选模式行,也不得改段落 */ + if (!InModeFlag) + return; /* 调音台:段落数字键不得注入假触摸(会打在推子底部,把数值打到 1) */ if (CurrUIProcress == UI_Mixer_Process) return; @@ -1140,13 +1140,12 @@ void FreeMode_PollEvenBeatStop(void) static void Band_MarkCleanStopped(void); static void Band_StopBeforeColdStart(void); -/* 扫描线程只投递:真正 Stop 在 MainTask,与拨片 Pick 同队列串行。 - * 若在扫描线程同步 Stop,会与 MainTask 拨片并发:Stop 期间 StartFlag 仍为 1, - * 拨片误判 Band_IsPlaying → 只改和弦不起奏,需再等 ~0.5s 才能拨响。 */ +/* 扫描线程只投递:真正 Stop 在 MainTask,与拨片 Pick 同队列串行, + * 避免扫描线程同步 Stop 与 MainTask 拨片并发。 */ void Stop_AutoBand_Request(void) { - /* ID=1:停止键软停(静音+停节拍,不调库 Stop,否则随后 Start 被吞) */ - MainTask_Sendmsg(MSG_ID_STOP_BAND, 1, 0, 0); + /* ID=0:硬停(AutoBandTop1_Stop)。软停已回退:库态与 UI 态必须一致。 */ + MainTask_Sendmsg(MSG_ID_STOP_BAND, 0, 0, 0); } static void Band_AllNotesOff(void) @@ -1161,30 +1160,18 @@ static void Band_AllNotesOff(void) } } -/* 停止键/偶拍收束:立刻静音并暂停库 1ms 节拍,不调用 AutoBandTop1_Stop。 - * 库 Stop 之后第一个 Start 必被吞,立即拨片无声。 */ +/* 兼容旧入口:一律硬停,不再做「只静音不停库」的软停。 */ void Stop_AutoBand_Soft(void) +{ + Stop_AutoBand(); +} + +void Stop_AutoBand(void) { Expert_RememberStopContext(); FreeMode_CancelEvenBeatStop(); Band_CancelStartFollowup(); - Band_TickGate = 0; - StartFlag = 0; - KEY_ID_1629 = 0; - Band_MarkCleanStopped(); - Band_AllNotesOff(); - s_outro_led_all_green = 0; - s_univ_preamble_flags = 0; - for (uint8_t i = 0; i < 4; i++) key_toggle[i] = 0; -} - -void Stop_AutoBand() -{ - Expert_RememberStopContext(); - FreeMode_CancelEvenBeatStop(); - /* 先清播放态,再 Stop/AllNoteOff,避免处理期间其它路径误判在播 */ - Band_CancelStartFollowup(); - Band_TickGate = 1; + Band_TickGate = 1; /* 始终喂库节拍;软停曾清 0,已撤销 */ StartFlag = 0; KEY_ID_1629 = 0; Band_MarkCleanStopped(); @@ -1192,8 +1179,7 @@ void Stop_AutoBand() Band_AllNotesOff(); s_outro_led_all_green = 0; s_univ_preamble_flags = 0; - //tick_ever_positive = false; - for(uint8_t i = 0;i < 4;i++) key_toggle[i] = 0; + for (uint8_t i = 0; i < 4; i++) key_toggle[i] = 0; } @@ -1235,93 +1221,33 @@ uint8_t BP_Transpose(uint8_t key_idx) * 供专业模式指板键区分「播放中换和弦」与「段落结束后续奏重启」。 */ static uint64_t s_play_tick_last = 0; static uint32_t s_play_adv_tick = 0; /* 最近一次 PlayTick 前进的系统 tick */ -/* 1=下次冷启动前需先 Stop 清库残留;0=Stop_AutoBand 已停干净,勿再 Stop。 */ -static uint8_t s_band_need_stop_before_start = 1; -/* 库特性(RTT 实测):真实停播后第一个完整 Start 被吞 - * (StartFlag=1 但 PlayTick 归 0 且不前进);第二次完整 Start 才起奏。 - * 哑 Start 不能用来吸收,会占住会话把真正起奏也吃掉。 */ -static uint8_t s_band_eater_armed = 0; static void Band_MarkCleanStopped(void) { s_play_tick_last = 0; s_play_adv_tick = 0; - s_band_need_stop_before_start = 0; } -/* 一切可能真实停播的 Stop 路径调用:武装「停后首启被吞」标记。 - * 宁可误武装(哑 Start 未被吞也只会被紧随的真实 Start 立刻重触发,无感), - * 不可漏武装(漏了用户就要拨两次)。 */ +/* 软停/吞噬器/补发起奏已撤销:保留空实现,避免其它调用点改动。 */ void Band_MarkRealStop(void) { - s_band_eater_armed = 1; -} - -/* 停后首个完整 Start 会被库吞掉(PlayTick 归 0 且不前进)。 - * 同一次调用里连发两次会被合成一次,仍然被吞;必须隔一拍再 Start。 - * 停后再起:先发本次 Start(可能被吞),再 20ms 后由 MainTask 补发一次。 */ -static uint8_t s_start_followup_pending; -static uint8_t s_start_followup_force; /* 1=补发中,禁止走「在播只换和弦」 */ -static rt_timer_t s_start_followup_timer; - -static uint8_t Band_TakeEaterArmed(void) -{ - uint8_t armed = s_band_eater_armed; - s_band_eater_armed = 0; - return armed; -} - -static void Band_StartFollowupTimerCb(void *parameter) -{ - (void)parameter; - MainTask_Sendmsg(MSG_ID_START_FOLLOWUP, 0, 0, 0); } void Band_CancelStartFollowup(void) { - s_start_followup_pending = 0; - s_start_followup_force = 0; - if (s_start_followup_timer != RT_NULL) - rt_timer_stop(s_start_followup_timer); } uint8_t Band_TakeStartFollowup(void) { - uint8_t pending = s_start_followup_pending; - s_start_followup_pending = 0; - return pending; + return 0; } void Band_BeginStartFollowup(void) { - s_start_followup_force = 1; } void Band_EndStartFollowup(void) { - s_start_followup_force = 0; -} - -static void Band_PostStartFollowup(void) -{ - if (s_start_followup_pending) - return; - s_start_followup_pending = 1; - if (s_start_followup_timer == RT_NULL) - { - s_start_followup_timer = rt_timer_create("bandFu", - Band_StartFollowupTimerCb, - RT_NULL, - 500, /* 库吞掉停后首启;约 0.5s 后再 Start 才生效 */ - RT_TIMER_FLAG_ONE_SHOT); - } - if (s_start_followup_timer != RT_NULL) - { - rt_timer_stop(s_start_followup_timer); - rt_timer_start(s_start_followup_timer); - } - else - MainTask_Sendmsg(MSG_ID_START_FOLLOWUP, 0, 0, 0); } static void Band_StartLocalRetry(uint8_t midi, uint8_t *notes, uint8_t n) @@ -1345,24 +1271,17 @@ static void Band_SyncStartRetry(void) void Band_AbsorbEatenStart(void) { - (void)0; } -/* 冷启动前按需 Stop:已由停止键停干净则跳过 */ +/* 冷启动前一律 Stop 清库残留(与软停前回退一致:不再「已软停则跳过」)。 */ static void Band_StopBeforeColdStart(void) { - if (s_band_need_stop_before_start) - { - Band_MarkRealStop(); /* 若库仍在播,此 Stop 会武装吞噬器,由紧随的吸收处理 */ - AutoBandTop1_Stop(); - } - s_band_need_stop_before_start = 1; + AutoBandTop1_Stop(); } -/* 诊断钩子:强制下次冷启动前先 Stop(RTT `band dirty`) */ +/* 诊断钩子:兼容 RTT `band dirty`(现冷启动本就会 Stop,保留空操作)。 */ void Band_ForceStopBeforeStart(void) { - s_band_need_stop_before_start = 1; } void Band_TrackPlayTick(void) @@ -1411,8 +1330,7 @@ static void Expert_StartWithChord(uint8_t chord_id, uint8_t *midi_note_buff, if (mGuiData[GUI_AUTOBAND_SW].Current) { /* 会话内勿 Stop:段落圆键切变奏后指板续奏若 Stop 会直接关音; - * 与节奏类型一致,仅换和弦/重进当前段。 - * 冷启动:仅当库可能仍有残留时才 Stop;停止键后已停干净则跳过。 */ + * 与节奏类型一致,仅换和弦/重进当前段。冷启动先 Stop 清残留。 */ if (!session) Band_StopBeforeColdStart(); AutoBandTop1_SetLoopMode(0, 1); @@ -1704,10 +1622,9 @@ void Pick_Handle() app_tm1629_all_on(LED_COLOR_G); if (mGuiData[GUI_AUTOBAND_SW].Current) { - /* 播放中再拨:Stop+Start 重启段落;停止键后已停则勿二次 Stop。 - * 此 Stop 若真实停播会武装库的吞噬器 → 紧随吸收 */ + /* 播放中再拨:Stop+Start 重启段落;冷启动前也先 Stop 清残留 */ if (session_was_on) - { Band_MarkRealStop(); AutoBandTop1_Stop(); } + AutoBandTop1_Stop(); else Band_StopBeforeColdStart(); AutoBandTop1_SetLoopMode(0,1); @@ -1738,8 +1655,7 @@ void Pick_Handle() case 1: /* 专业:播放中再拨片不 Stop+Start(库会把未消费的 Start 标志清掉 → 静音); * 本地曲播放中仅换和弦音续播,节奏路径 piece 重启本就安全。 */ - if (!s_start_followup_force && - Band_IsPlaying() && mGuiData[GUI_AUTOBAND_SW].Current) + if (Band_IsPlaying() && mGuiData[GUI_AUTOBAND_SW].Current) { Accomp_UpdatePlayingChord(); LOG_I("pick", "expert/pick skip restart playing chord=%u", (unsigned)chord_id); diff --git a/Global/Global.h b/Global/Global.h index c8ef3a4..54020bf 100644 --- a/Global/Global.h +++ b/Global/Global.h @@ -32,8 +32,8 @@ #define MSG_ID_BLE_UI_REFRESH 28 #define MSG_ID_BLE_STYLE_SET 29 #define MSG_ID_LOW_BAT_TIP 30 -#define MSG_ID_STOP_BAND 31 /* 停止键/收束:MainTask 串行 Stop,避免与拨片起奏竞态 */ -#define MSG_ID_START_FOLLOWUP 32 /* 停后首启被库吞:下一拍补发真正起奏 */ +#define MSG_ID_STOP_BAND 31 /* 停止键/收束:MainTask 串行硬停 */ +#define MSG_ID_START_FOLLOWUP 32 /* 保留:软停补发已撤销,不再使用 */ #define GPIO_PIN_RESET false #define GPIO_PIN_SET true @@ -241,16 +241,16 @@ void TM1629_Handle(uint8_t key); void Pick_Handle(); void Loop_Light_Handle(uint8_t measure); void Stop_AutoBand(void); -void Stop_AutoBand_Soft(void); +void Stop_AutoBand_Soft(void); /* 兼容:等同 Stop_AutoBand */ extern uint8_t Band_TickGate; -void Stop_AutoBand_Request(void); +void Stop_AutoBand_Request(void); /* 投递 MSG_ID_STOP_BAND → 硬停 */ uint8_t Band_IsPlaying(void); -void Band_ForceStopBeforeStart(void); -void Band_AbsorbEatenStart(void); -void Band_MarkRealStop(void); -uint8_t Band_TakeStartFollowup(void); -void Band_BeginStartFollowup(void); -void Band_EndStartFollowup(void); +void Band_ForceStopBeforeStart(void); /* 兼容空操作 */ +void Band_AbsorbEatenStart(void); /* 兼容空操作 */ +void Band_MarkRealStop(void); /* 兼容空操作 */ +uint8_t Band_TakeStartFollowup(void); /* 兼容:恒返回 0 */ +void Band_BeginStartFollowup(void); /* 兼容空操作 */ +void Band_EndStartFollowup(void); /* 兼容空操作 */ void BL_Set_led(uint8_t Led, uint8_t chord_type); diff --git a/task/task_init.c b/task/task_init.c index d80875d..1de1910 100644 --- a/task/task_init.c +++ b/task/task_init.c @@ -111,22 +111,12 @@ void TaskMainThread_entry(void* parameter) Pick_Handle(); break; case MSG_ID_STOP_BAND: + /* 停止键/偶拍收束:MainTask 串行硬停(已撤销软停) */ if (!System_LowBat_IsActive()) - { - if (xEvent.ID) - Stop_AutoBand_Soft(); - else - Stop_AutoBand(); - } + Stop_AutoBand(); break; case MSG_ID_START_FOLLOWUP: - /* 停后补发:强制再 Start,勿因 NotifyPlayActivity 误判「在播」只换和弦 */ - if (!System_LowBat_IsActive() && InModeFlag && Band_TakeStartFollowup()) - { - Band_BeginStartFollowup(); - Pick_Handle(); - Band_EndStartFollowup(); - } + /* 软停补发路径已撤销;保留 case 以免旧固件消息号撞车 */ break; case MSG_ID_LOOP_LIGHT: if (!System_LowBat_IsActive()) @@ -179,8 +169,14 @@ void TaskBTHandleThread_entry(void* parameter) case MSG_ID_PITCH_OFFSET : BT_Pitch_offset_map(xEvent.ID,xEvent.HiByte); break; case MSG_ID_CHORD_OFFSET : BT_Chord_offset_map(xEvent.ID,xEvent.HiByte); break; /* BLE section / intro-outro-end commands (06 xx, 04 07) */ - case MSG_ID_ADCIN1KEY : ADC_IN1_KEY_Handle((uint8_t)xEvent.ID, true); break; - case MSG_ID_KEY_1617 : TM1617_Handle((uint8_t)xEvent.ID); break; + case MSG_ID_ADCIN1KEY: + if (InModeFlag) + ADC_IN1_KEY_Handle((uint8_t)xEvent.ID, true); + break; + case MSG_ID_KEY_1617: + if (InModeFlag) + TM1617_Handle((uint8_t)xEvent.ID); + break; } } }