fix: universal outro all-green LED; expert local song keeps playing after section+fret

Keep fretboard LEDs all green during outro, and for expert local songs treat section-key + fret changes as continuous chord updates like rhythm mode (no mid-session Stop).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yuquanjun 2026-09-21 15:13:53 +08:00
parent 7ebb7cf265
commit 8fa5220b82
3 changed files with 53 additions and 8 deletions

View File

@ -612,6 +612,9 @@ void Accomp_UpdatePlayingChord(void)
AutoBandTop1_Note_On(midi_note_buff[i], 0x50);
}
/* 尾奏期间冻结走向灯:保持全绿,避免 LOOP_LIGHT 按小节刷红 */
static uint8_t s_outro_led_all_green = 0;
/* 尾奏起奏:Postamble(0) + 同步起奏 + 当前和弦 Note_On。
* 供 ADC 独立尾奏键与万能模式第4段落键共用。
* 万能走 piece 循环,须先退出 piece,否则 Postamble 舞台切不过去;
@ -627,6 +630,9 @@ void AutoBand_StartOutro(void)
/* 退出和弦走向 piece,再进风格尾奏舞台 */
AutoBandTop1_SetPiecePlayMode(0, 0, 0);
AutoBandTop1_Postamble(0);
/* 尾奏:指板 LED 全绿(停走 LOOP 走向红灯) */
s_outro_led_all_green = 1;
app_tm1629_all_on(LED_COLOR_G);
/* 尾奏起奏前补发主音量,保证与图标一致 */
MasterVolume_Reapply();
AutoBandTop1_SyncStart();
@ -654,6 +660,7 @@ void ADC_IN1_KEY_Handle(uint8_t key,bool on)
}
else
{
s_outro_led_all_green = 0; /* 前奏/断奏:恢复走向灯 */
switch(key)
{
case 3: AutoBandTop1_Preamble(0); is_preamble = 1; break;
@ -765,6 +772,7 @@ void Stop_AutoBand()
SendMidiDataToDreamDSP(AllControlOff_buff,sizeof(AllControlOff_buff));
}
StartFlag = 0;
s_outro_led_all_green = 0;
//tick_ever_positive = false;
for(uint8_t i = 0;i < 4;i++) key_toggle[i] = 0;
}
@ -826,6 +834,15 @@ void Band_TrackPlayTick(void)
}
}
/* 段落键 SetRunVar 后 PlayTick 可能短暂不变;主动刷新以免误判为已停。 */
void Band_NotifyPlayActivity(void)
{
if (!StartFlag)
return;
s_play_tick_last = AutoBandTop1_GetCurrentPlayTick();
s_play_adv_tick = rt_tick_get();
}
uint8_t Band_IsPlaying(void)
{
if (!StartFlag || s_play_adv_tick == 0)
@ -839,16 +856,21 @@ static void Expert_StartWithChord(uint8_t chord_id, uint8_t *midi_note_buff,
uint8_t note_cnt, const char *trigger)
{
uint8_t midi = 0;
uint8_t session = StartFlag ? 1u : 0u;
StartFlag = 1;
if (mGuiData[GUI_AUTOBAND_SW].Current)
{
AutoBandTop1_Stop();
/* 会话内勿 Stop:段落圆键切变奏后指板续奏若 Stop 会直接关音;
* 与节奏类型一致,仅换和弦/重进当前段。冷启动仍 Stop 清残留。 */
if (!session)
AutoBandTop1_Stop();
AutoBandTop1_SetLoopMode(0, 1);
AutoBandTop1_SetRunVar(mGuiData[GUI_PLAY_SECTION].Current);
midi = 0x3C + mGuiData[GUI_TRANSPOSE].Current;
AutoBandTop1_StartWithNote(midi);
AutoBandTop1_StartWithNotes(midi_note_buff, note_cnt);
Band_NotifyPlayActivity();
LOG_I("pick", "local/expert root=%u name=%s sw=%u tab=%u trigger=%s chord=%u",
midi,
AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "?",
@ -862,6 +884,7 @@ static void Expert_StartWithChord(uint8_t chord_id, uint8_t *midi_note_buff,
AutoBandTop1_SetPiecePlayMode(1, 0, 1920);
AutoBandTop1_StartWithNotes(midi_note_buff, note_cnt);
AutoBandTop1_SetLoopMode(0, 1);
Band_NotifyPlayActivity();
LOG_I("pick", "expert/rhythm piece name=%s trigger=%s chord=%u",
AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "?",
trigger,
@ -958,11 +981,24 @@ void TM1629_Handle(uint8_t key)
* 松手再按同一键也必须能续奏(与「指板+拨片」一致,拨片本无去重) */
if (!Band_IsPlaying())
{
/* 段落已停:仅按指板续奏下一节。转主任务走 Pick_Handle
*(与「指板+拨片」等价)。勿在播放中 Stop+Start——本地曲目
* 中途重启常静音,表现为换把位关音、再按才有声。 */
MainTask_Sendmsg(MSG_ID_BP_KEY, 0, 0, 0);
LOG_I("pick", "expert/fret continue chord=%u", (unsigned)KEY_ID_1629);
/* 节奏:段落自然停后指板续奏 → piece 重启。
* 本地曲:圆键切段后 PlayTick 常短暂停滞,若走 Stop+Start 会关音;
* 与节奏「播放中换把」一致,仅换和弦音持续播放。段落后续奏用拨片/再按圆键。 */
if (mGuiData[GUI_AUTOBAND_SW].Current)
{
uint8_t midi_note_buff[4] = {0,};
uint8_t note_cnt = GetChordNotesByType(KEY_ID_1629,chord_type_index_map[KEY_ID_1629].type,midi_note_buff);
for(uint8_t i = 0;i < note_cnt;i++)
AutoBandTop1_Note_On(midi_note_buff[i],0x50);
Return_Light_buff(KEY_ID_1629);
Band_NotifyPlayActivity();
LOG_I("pick", "expert/fret change(local) chord=%u", (unsigned)KEY_ID_1629);
}
else
{
MainTask_Sendmsg(MSG_ID_BP_KEY, 0, 0, 0);
LOG_I("pick", "expert/fret continue chord=%u", (unsigned)KEY_ID_1629);
}
}
else
{
@ -1120,6 +1156,7 @@ void Pick_Handle()
case 0:
/* 万能:和弦走向用 piece 模式;须 SetLoopMode,否则无循环时常听不到伴奏 */
StartFlag = 1;
s_outro_led_all_green = 0; /* 拨片重开 piece,恢复走向灯 */
AutoBandTop1_SetPiecePlayMode(1, 0, 480);
AutoBandTop1_StartWithNotes(midi_note_buff, note_cnt);
AutoBandTop1_SetLoopMode(0, 1);
@ -1601,7 +1638,8 @@ void Read_Cur_Measure()
Band_TrackPlayTick();
if (loop_light_ok && StartFlag)
/* 尾奏中保持全绿,不刷新和弦走向红灯 */
if (loop_light_ok && StartFlag && !s_outro_led_all_green)
{
if(now - last_tick_i >= 10)
{

View File

@ -238,6 +238,8 @@ void BL_Set_led(uint8_t Led, uint8_t chord_type);
uint8_t GetChordNotesByType(uint8_t MIDI_Index,uint8_t type,uint8_t *buff);
/* 伴奏已在播时仅更新和弦音,不 Restart(快转调) */
void Accomp_UpdatePlayingChord(void);
/* 段落键等主动刷新伴奏活动,避免 PlayTick 短暂停滞被判为已停 */
void Band_NotifyPlayActivity(void);
void BT_Chord_offset_map(uint8_t pos_offset,uint8_t chord_offset);
void BT_Pitch_offset_map(uint8_t pos_offset,uint8_t pitch_offset);
void Read_Cur_Measure();

View File

@ -278,12 +278,17 @@ void Touch_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex,uint8_t value)
{
mGuiData[ID].Current = value;
AutoBandTop1_SetRunVar(mGuiData[ID].Current);
/* 专业本地曲:切段后 PlayTick 可能短暂不变,刷新活动以免随后指板误走 Stop */
if (StartFlag)
Band_NotifyPlayActivity();
}else
{
/* 触摸起奏前补发主音量,保证实际音量与图标一致 */
MasterVolume_Reapply();
AutoBandTop1_FillinWithIndex(value);
AutoBandTop1_Start();
if (StartFlag)
Band_NotifyPlayActivity();
}
if (!UI_SetFocus(GUI_PLAY_SECTION))
Refresh_SectionSelect(last_value, &UI_Label[ID], &mGuiData[ID]);