feat(free): allow pick start without fretboard using expert-stop key

Normal-mode pick with no fret held applies the last expert stop transpose, starts on I, and arms even-beat stop if idle.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yuquanjun 2026-09-24 07:43:46 +08:00
parent 5c30baef89
commit e7c9cd91f1
1 changed files with 59 additions and 16 deletions

View File

@ -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,23}; /* major.minor.patch — 0.2.23: 万能拨片先前奏再循环段落1 */
const uint8_t Version[3] = {0,2,24}; /* major.minor.patch — 0.2.24: 普通无指板也可拨片起奏(用专业停键调性)+偶拍停 */
uint8_t Led = 8;
bool PressFlag = 0;
@ -647,6 +647,33 @@ void Accomp_ApplyDefaultIChord(void)
PressFlag = 0;
}
/* 专业模式按停止键时记住当前调性,供普通模式无指板拨片起奏使用 */
static uint8_t s_expert_stop_transpose = 0;
static uint8_t s_expert_stop_transpose_valid = 0;
static void Expert_RememberStopTranspose(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;
s_expert_stop_transpose_valid = 1;
}
}
/* 普通无指板拨片:套用上次专业停键调性(无记录则保持当前移调) */
static void FreeMode_ApplyExpertStopTranspose(void)
{
if (!s_expert_stop_transpose_valid)
return;
if ((uint8_t)mGuiData[GUI_TRANSPOSE].Current == s_expert_stop_transpose)
return;
mGuiData[GUI_TRANSPOSE].Current = s_expert_stop_transpose;
UITask_Sendmsg(MSG_ID_BLE_UI_REFRESH, GUI_TRANSPOSE, 0, 0);
}
void Accomp_UpdatePlayingChord(void)
{
uint8_t midi_note_buff[4] = {0,};
@ -684,6 +711,7 @@ extern uint8_t m_ABSystem[];
#define AB_STAGE_POST 0x0Cu
static void FreeMode_CancelEvenBeatStop(void);
static void FreeMode_ArmEvenBeatStop(void);
static void Accomp_FireSectionNotes(void)
{
@ -1092,6 +1120,7 @@ static void Band_AllNotesOff(void)
* 库 Stop 之后第一个 Start 必被吞,立即拨片无声。 */
void Stop_AutoBand_Soft(void)
{
Expert_RememberStopTranspose();
FreeMode_CancelEvenBeatStop();
Band_CancelStartFollowup();
Band_TickGate = 0;
@ -1107,6 +1136,7 @@ void Stop_AutoBand_Soft(void)
void Stop_AutoBand()
{
Expert_RememberStopTranspose();
FreeMode_CancelEvenBeatStop();
/* 先清播放态,再 Stop/AllNoteOff,避免处理期间其它路径误判在播 */
Band_CancelStartFollowup();
@ -1546,9 +1576,20 @@ void Pick_Handle()
return;
}
/* 左手未触发和弦板(或落在拍速/停止键)时:拨片默认发当前调一级大和弦伴奏;
* 普通模式除外——必须左手按住指板再拨,不做一级兜底(说明书需求) */
if (mGuiData[GUI_TAB_INDEX].Current != 2 &&
/* 左手未触发和弦板(或落在拍速/停止键)时:拨片默认发当前调一级大和弦伴奏。
* 普通模式无指板也可起奏:调性用上次专业停键时的移调,起奏后无操作则偶拍停。 */
{
uint8_t free_pick_no_fret =
(mGuiData[GUI_TAB_INDEX].Current == 2 &&
(PressFlag == 0 || chord_id == 0 || chord_id > 21)) ? 1u : 0u;
if (free_pick_no_fret)
{
FreeMode_ApplyExpertStopTranspose();
Accomp_ApplyDefaultIChord();
chord_id = KEY_ID_1629;
}
else if (mGuiData[GUI_TAB_INDEX].Current != 2 &&
(chord_id == 0 || chord_id == 22 || chord_id == 23))
{
Accomp_ApplyDefaultIChord();
@ -1592,14 +1633,9 @@ void Pick_Handle()
break;
case 2:
/* 普通:左手按住指板 + 拨片起奏;松手由 TM1629 停。
/* 普通:可无指板拨片起奏(一级+专业停键调性);有指板则用当前和弦。
* 无指板起奏后若无其它操作,偶拍末停;按住指板则循环至松手再偶拍停。
* 节奏用 piece;本地曲目用 StartWithNote */
if (PressFlag == 0 || chord_id == 0 || chord_id > 21)
{
LOG_I("pick", "normal skip press=%u chord=%u (need fretboard)",
(unsigned)PressFlag, (unsigned)chord_id);
break;
}
{
uint8_t session_was_on = StartFlag ? 1u : 0u;
StartFlag = 1;
@ -1617,18 +1653,24 @@ void Pick_Handle()
AutoBandTop1_SetRunVar(mGuiData[GUI_PLAY_SECTION].Current);
midi = 0x3C + mGuiData[GUI_TRANSPOSE].Current;
Band_StartLocalRetry(midi, midi_note_buff, note_cnt);
LOG_I("pick", "local/normal root=%u name=%s", midi,
AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "?");
LOG_I("pick", "local/normal root=%u name=%s noFret=%u", midi,
AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "?",
(unsigned)free_pick_no_fret);
}
else
{
AutoBandTop1_SetPiecePlayMode(1, 0, 1920);
Band_StartPieceRetry(midi_note_buff, note_cnt);
AutoBandTop1_SetLoopMode(0, 1);
LOG_I("pick", "normal/rhythm piece name=%s notes=%u chord=%u",
LOG_I("pick", "normal/rhythm piece name=%s notes=%u chord=%u noFret=%u xp=%u",
AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "?",
(unsigned)note_cnt, (unsigned)chord_id);
(unsigned)note_cnt, (unsigned)chord_id,
(unsigned)free_pick_no_fret,
(unsigned)mGuiData[GUI_TRANSPOSE].Current);
}
/* 无指板:起奏后即武装偶拍停;有指板则等松手再 Arm */
if (free_pick_no_fret)
FreeMode_ArmEvenBeatStop();
}
break;
@ -1653,6 +1695,7 @@ void Pick_Handle()
break;
}
}
}
/* 指板灯本色:与 App 引导灯一致(含黄/紫/青/白合成色) */