From 4bfe3ca008b3dad45bd40163bc0a9120799b7e23 Mon Sep 17 00:00:00 2001 From: yuquanjun Date: Thu, 24 Sep 2026 08:05:50 +0800 Subject: [PATCH] fix(free): preserve expert chord/transpose across mode switch NavBar no longer forces I after stop; remember context before leave and prefer saved fret chord on no-fret pick. Co-authored-by: Cursor --- Global/Global.c | 57 +++++++++++++++++++++++++++++++----------------- Global/Global.h | 2 ++ UI/UI_SongMode.c | 2 ++ UI/UI_global.c | 6 ++--- 4 files changed, 44 insertions(+), 23 deletions(-) diff --git a/Global/Global.c b/Global/Global.c index 85e676f..64ff595 100644 --- a/Global/Global.c +++ b/Global/Global.c @@ -105,7 +105,7 @@ int16_t MIC_VOL_MAP[11]= {-9000,-7000,-5000,-3000,-1000,1000,3000,5000,7000,9000 uint8_t TOUCH_AREA_NUM = (sizeof(Touch_Areas)/sizeof(Touch_AreaTypeDef)); -const uint8_t Version[3] = {0,2,25}; /* major.minor.patch — 0.2.25: 普通无指板拨片沿用专业最后指板和弦 */ +const uint8_t Version[3] = {0,2,27}; /* major.minor.patch — 0.2.27: 切模式前记专业移调/指板;无指板拨片优先用记忆 */ uint8_t Led = 8; bool PressFlag = 0; @@ -648,9 +648,9 @@ void Accomp_ApplyDefaultIChord(void) } /* 专业/普通共用:最后一次指板和弦(供普通无指板拨片)。 - * 另记专业停键时的移调:0xFF=尚未在专业停过;移调合法值 0~11。 + * 另记专业侧移调:0xFF=尚未记下;移调合法值 0~11。 * chord: 0=无记录;1~21=指板键。 */ -static uint8_t s_expert_stop_transpose = 0xFFu; +static uint8_t s_saved_transpose = 0xFFu; static uint8_t s_last_fret_chord = 0; static void Accomp_RememberLastFretChord(uint8_t key) @@ -659,14 +659,20 @@ static void Accomp_RememberLastFretChord(uint8_t key) s_last_fret_chord = key; } -static void Expert_RememberStopContext(void) +static void Accomp_RememberTranspose(void) +{ + s_saved_transpose = (uint8_t)mGuiData[GUI_TRANSPOSE].Current; +} + +/* 停键或切模式前:按当前页记住和弦;专业再记移调 */ +void Accomp_RememberPlayContext(void) { uint8_t tab = (uint8_t)mGuiData[GUI_TAB_INDEX].Current; uint8_t last = (uint8_t)mGuiData[GUI_TAB_LAST_INDEX].Current; if (tab == 1 || (tab == 3 && last == 1)) { - s_expert_stop_transpose = (uint8_t)mGuiData[GUI_TRANSPOSE].Current; + Accomp_RememberTranspose(); Accomp_RememberLastFretChord(KEY_ID_1629); } else if (tab == 2 || (tab == 3 && last == 2)) @@ -675,28 +681,35 @@ static void Expert_RememberStopContext(void) } } -/* 普通无指板拨片:移调用专业停键值;和弦用专业/普通记下的最后指板,否则一级 */ +static void Expert_RememberStopContext(void) +{ + Accomp_RememberPlayContext(); +} + +/* 普通无指板拨片:优先用记下的最后指板和弦(勿信切模式后的默认 KEY=一级); + * 移调用专业侧记下的值;都没有才退回一级。 */ static void FreeMode_ApplyLastFretChordForNoFretPick(void) { - if (s_expert_stop_transpose != 0xFFu && - (uint8_t)mGuiData[GUI_TRANSPOSE].Current != s_expert_stop_transpose) + if (s_saved_transpose != 0xFFu && + (uint8_t)mGuiData[GUI_TRANSPOSE].Current != s_saved_transpose) { - mGuiData[GUI_TRANSPOSE].Current = s_expert_stop_transpose; + mGuiData[GUI_TRANSPOSE].Current = s_saved_transpose; UITask_Sendmsg(MSG_ID_BLE_UI_REFRESH, GUI_TRANSPOSE, 0, 0); } - if (KEY_ID_1629 >= 1u && KEY_ID_1629 <= 21u) - { - Accomp_RememberLastFretChord(KEY_ID_1629); - PressFlag = 0; - return; - } + /* 切模式 NavBar 会把 KEY 打成一级,必须以记忆为准 */ if (s_last_fret_chord >= 1u && s_last_fret_chord <= 21u) { KEY_ID_1629 = s_last_fret_chord; PressFlag = 0; return; } + if (KEY_ID_1629 >= 1u && KEY_ID_1629 <= 21u) + { + Accomp_RememberLastFretChord(KEY_ID_1629); + PressFlag = 0; + return; + } Accomp_ApplyDefaultIChord(); } @@ -1482,12 +1495,16 @@ void TM1629_Handle(uint8_t key) } uint8_t group = (key - 1) / 3; /* 1~3→0, 4~6→1, ..., 19~21→6 */ KEY_ID_1629 = key; - /* 专业/普通(及对应设置页):记下最后指板和弦,供普通无指板拨片沿用 */ + /* 专业/普通(及对应设置页):记下最后指板和弦;专业同时记移调 */ { uint8_t tab = (uint8_t)mGuiData[GUI_TAB_INDEX].Current; uint8_t last = (uint8_t)mGuiData[GUI_TAB_LAST_INDEX].Current; - if (tab == 1 || tab == 2 || - (tab == 3 && (last == 1 || last == 2))) + if (tab == 1 || (tab == 3 && last == 1)) + { + Accomp_RememberTranspose(); + Accomp_RememberLastFretChord(key); + } + else if (tab == 2 || (tab == 3 && last == 2)) Accomp_RememberLastFretChord(key); } MIDI = (STRING_MIDI *)Chord_Midi_Table[group]; @@ -1610,7 +1627,7 @@ void Pick_Handle() } /* 左手未触发和弦板(或落在拍速/停止键)时:拨片默认发当前调一级大和弦伴奏。 - * 普通无指板也可起奏:用专业最后指板和弦(如 VI),无记录才退回一级;无操作则偶拍停。 */ + * 普通无指板也可起奏:用专业/普通记下的最后指板和弦,无记录才退回一级;无操作则偶拍停。 */ { uint8_t free_pick_no_fret = (mGuiData[GUI_TAB_INDEX].Current == 2 && @@ -1618,7 +1635,7 @@ void Pick_Handle() if (free_pick_no_fret) { - FreeMode_ApplyExpertChordForNoFretPick(); + FreeMode_ApplyLastFretChordForNoFretPick(); chord_id = KEY_ID_1629; } else if (mGuiData[GUI_TAB_INDEX].Current != 2 && diff --git a/Global/Global.h b/Global/Global.h index b8b1414..9608dbe 100644 --- a/Global/Global.h +++ b/Global/Global.h @@ -257,6 +257,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); +/* 切模式/停键前记住专业移调与最后指板和弦 */ +void Accomp_RememberPlayContext(void); /* 段落键等主动刷新伴奏活动,避免 PlayTick 短暂停滞被判为已停 */ void Band_NotifyPlayActivity(void); void BT_Chord_offset_map(uint8_t pos_offset,uint8_t chord_offset); diff --git a/UI/UI_SongMode.c b/UI/UI_SongMode.c index 1e7cde1..7e5bc1f 100644 --- a/UI/UI_SongMode.c +++ b/UI/UI_SongMode.c @@ -303,6 +303,8 @@ void Touch_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex,uint8_t value) { if(mGuiData[ID].Current != value) { + /* 改 TAB 前先记住当前专业/普通指板与移调 */ + Accomp_RememberPlayContext(); mGuiData[ID].Current = value; app_tm1629_all_on(LED_COLOR_G); diff --git a/UI/UI_global.c b/UI/UI_global.c index e5735bd..0129ade 100644 --- a/UI/UI_global.c +++ b/UI/UI_global.c @@ -1049,15 +1049,15 @@ void UI_NavBar_Action(uint8_t value) { /* 离开万能后 LOOP_LIGHT 停更,须显式恢复全绿(旧 GUI_TAB_INDEX 路径曾做) */ app_tm1629_all_on(LED_COLOR_G); - /* 底栏切模式/进设置:立即结束当前伴奏(设置页不走 ReloadTonePreset) */ + /* 先记住当前专业/普通的指板与移调,再停;勿再强制一级(会盖掉记忆供普通无指板拨片) */ + Accomp_RememberPlayContext(); Stop_AutoBand(); - /* 切模式后拨片/前奏默认当前调一级 */ - Accomp_ApplyDefaultIChord(); switch (value) { case UI0902_NAV_UNIVERSAL: /* Init 内会设 TAB 并 ReloadTonePreset,勿在此前加载(会仍用旧 TAB) */ + Accomp_ApplyDefaultIChord(); /* 万能拨片默认一级 */ MenuPage_SongMode_Proc(); break; case UI0902_NAV_NORMAL: