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 <cursoragent@cursor.com>
This commit is contained in:
parent
18394d0b9b
commit
67a5fe5d60
|
|
@ -79,6 +79,8 @@ uint8_t app_tm1617_scan_key(void)
|
|||
{
|
||||
key_last = key;
|
||||
LOG_I("KEY", "tm1617 key=%u", (unsigned)key);
|
||||
/* ????????????????/?????? */
|
||||
if (InModeFlag)
|
||||
TM1617_Handle(key);
|
||||
return key;
|
||||
}
|
||||
|
|
|
|||
124
Global/Global.c
124
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)
|
||||
{
|
||||
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;
|
||||
Stop_AutoBand();
|
||||
}
|
||||
|
||||
void Stop_AutoBand()
|
||||
void Stop_AutoBand(void)
|
||||
{
|
||||
Expert_RememberStopContext();
|
||||
FreeMode_CancelEvenBeatStop();
|
||||
/* 先清播放态,再 Stop/AllNoteOff,避免处理期间其它路径误判在播 */
|
||||
Band_CancelStartFollowup();
|
||||
Band_TickGate = 1;
|
||||
Band_TickGate = 1; /* 始终喂库节拍;软停曾清 0,已撤销 */
|
||||
StartFlag = 0;
|
||||
KEY_ID_1629 = 0;
|
||||
Band_MarkCleanStopped();
|
||||
|
|
@ -1192,7 +1179,6 @@ 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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/* 诊断钩子:强制下次冷启动前先 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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue