fix(free): keep expert fret chord (e.g. VI) for no-fret pick

Do not force I on free pick; reuse last expert KEY_ID / remembered chord after mode switch.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yuquanjun 2026-09-24 07:53:57 +08:00
parent a322ed369c
commit 9ae3f5ec5e
1 changed files with 43 additions and 14 deletions

View File

@ -647,30 +647,55 @@ void Accomp_ApplyDefaultIChord(void)
PressFlag = 0; PressFlag = 0;
} }
/* 专业模式按停止键时记住当前调性,供普通模式无指板拨片起奏使用。 /* 专业模式:记住停键时的移调,以及最后一次指板和弦(供普通无指板拨片)。
* 0xFF=尚未在专业停过;移调合法值 0~11。 */ * transpose: 0xFF=尚未在专业停过;移调合法值 0~11。
* chord: 0=无记录;1~21=指板键。 */
static uint8_t s_expert_stop_transpose = 0xFFu; static uint8_t s_expert_stop_transpose = 0xFFu;
static uint8_t s_expert_last_chord = 0;
static void Expert_RememberStopTranspose(void) static void Expert_RememberLastChord(uint8_t key)
{
if (key >= 1u && key <= 21u)
s_expert_last_chord = key;
}
static void Expert_RememberStopContext(void)
{ {
uint8_t tab = (uint8_t)mGuiData[GUI_TAB_INDEX].Current; uint8_t tab = (uint8_t)mGuiData[GUI_TAB_INDEX].Current;
uint8_t last = (uint8_t)mGuiData[GUI_TAB_LAST_INDEX].Current; uint8_t last = (uint8_t)mGuiData[GUI_TAB_LAST_INDEX].Current;
if (tab == 1 || (tab == 3 && last == 1)) if (tab == 1 || (tab == 3 && last == 1))
{
s_expert_stop_transpose = (uint8_t)mGuiData[GUI_TRANSPOSE].Current; s_expert_stop_transpose = (uint8_t)mGuiData[GUI_TRANSPOSE].Current;
Expert_RememberLastChord(KEY_ID_1629);
}
} }
/* 普通无指板拨片:套用上次专业停键调性(无记录则保持当前移调) */ /* 普通无指板拨片:移调用专业停键值;和弦优先当前 KEY,否则专业最后指板,再否则一级 */
static void FreeMode_ApplyExpertStopTranspose(void) static void FreeMode_ApplyExpertChordForNoFretPick(void)
{
if (s_expert_stop_transpose != 0xFFu &&
(uint8_t)mGuiData[GUI_TRANSPOSE].Current != s_expert_stop_transpose)
{ {
if (s_expert_stop_transpose == 0xFFu)
return;
if ((uint8_t)mGuiData[GUI_TRANSPOSE].Current == s_expert_stop_transpose)
return;
mGuiData[GUI_TRANSPOSE].Current = s_expert_stop_transpose; mGuiData[GUI_TRANSPOSE].Current = s_expert_stop_transpose;
UITask_Sendmsg(MSG_ID_BLE_UI_REFRESH, GUI_TRANSPOSE, 0, 0); UITask_Sendmsg(MSG_ID_BLE_UI_REFRESH, GUI_TRANSPOSE, 0, 0);
} }
if (KEY_ID_1629 >= 1u && KEY_ID_1629 <= 21u)
{
Expert_RememberLastChord(KEY_ID_1629);
PressFlag = 0;
return;
}
if (s_expert_last_chord >= 1u && s_expert_last_chord <= 21u)
{
KEY_ID_1629 = s_expert_last_chord;
PressFlag = 0;
return;
}
Accomp_ApplyDefaultIChord();
}
void Accomp_UpdatePlayingChord(void) void Accomp_UpdatePlayingChord(void)
{ {
uint8_t midi_note_buff[4] = {0,}; uint8_t midi_note_buff[4] = {0,};
@ -1118,7 +1143,7 @@ static void Band_AllNotesOff(void)
* 库 Stop 之后第一个 Start 必被吞,立即拨片无声。 */ * 库 Stop 之后第一个 Start 必被吞,立即拨片无声。 */
void Stop_AutoBand_Soft(void) void Stop_AutoBand_Soft(void)
{ {
Expert_RememberStopTranspose(); Expert_RememberStopContext();
FreeMode_CancelEvenBeatStop(); FreeMode_CancelEvenBeatStop();
Band_CancelStartFollowup(); Band_CancelStartFollowup();
Band_TickGate = 0; Band_TickGate = 0;
@ -1133,7 +1158,7 @@ void Stop_AutoBand_Soft(void)
void Stop_AutoBand() void Stop_AutoBand()
{ {
Expert_RememberStopTranspose(); Expert_RememberStopContext();
FreeMode_CancelEvenBeatStop(); FreeMode_CancelEvenBeatStop();
/* 先清播放态,再 Stop/AllNoteOff,避免处理期间其它路径误判在播 */ /* 先清播放态,再 Stop/AllNoteOff,避免处理期间其它路径误判在播 */
Band_CancelStartFollowup(); Band_CancelStartFollowup();
@ -1453,6 +1478,11 @@ void TM1629_Handle(uint8_t key)
} }
uint8_t group = (key - 1) / 3; /* 1~3→0, 4~6→1, ..., 19~21→6 */ uint8_t group = (key - 1) / 3; /* 1~3→0, 4~6→1, ..., 19~21→6 */
KEY_ID_1629 = key; KEY_ID_1629 = key;
/* 专业(及设置页来自专业):记下指板和弦,供切普通后无指板拨片沿用 */
if (mGuiData[GUI_TAB_INDEX].Current == 1 ||
(mGuiData[GUI_TAB_INDEX].Current == 3 &&
mGuiData[GUI_TAB_LAST_INDEX].Current == 1))
Expert_RememberLastChord(key);
MIDI = (STRING_MIDI *)Chord_Midi_Table[group]; MIDI = (STRING_MIDI *)Chord_Midi_Table[group];
ORGAN_MIDI = OrganChord_Midi_Table[group]; ORGAN_MIDI = OrganChord_Midi_Table[group];
@ -1573,7 +1603,7 @@ void Pick_Handle()
} }
/* 左手未触发和弦板(或落在拍速/停止键)时:拨片默认发当前调一级大和弦伴奏。 /* 左手未触发和弦板(或落在拍速/停止键)时:拨片默认发当前调一级大和弦伴奏。
* 普通模式无指板也可起奏:调性用上次专业停键时的移调,起奏后无操作则偶拍停。 */ * 普通无指板也可起奏:用专业最后指板和弦(如 VI),无记录才退回一级;无操作则偶拍停。 */
{ {
uint8_t free_pick_no_fret = uint8_t free_pick_no_fret =
(mGuiData[GUI_TAB_INDEX].Current == 2 && (mGuiData[GUI_TAB_INDEX].Current == 2 &&
@ -1581,8 +1611,7 @@ void Pick_Handle()
if (free_pick_no_fret) if (free_pick_no_fret)
{ {
FreeMode_ApplyExpertStopTranspose(); FreeMode_ApplyExpertChordForNoFretPick();
Accomp_ApplyDefaultIChord();
chord_id = KEY_ID_1629; chord_id = KEY_ID_1629;
} }
else if (mGuiData[GUI_TAB_INDEX].Current != 2 && else if (mGuiData[GUI_TAB_INDEX].Current != 2 &&