fix(free): stop accompaniment on next even beat after fret release
In normal mode, releasing the fretboard now finishes the current beat-pair (beat 1→end of 2, beat 3→end of 4) instead of cutting immediately. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
8fa5220b82
commit
158c02d27b
106
Global/Global.c
106
Global/Global.c
|
|
@ -761,8 +761,106 @@ void Tap_to_Speed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 普通模式松手:对齐到下一偶拍末再停(拍1→拍2末,拍3→拍4末)。
|
||||||
|
* piece 窗口 1920=4 拍,每拍 480 tick(与起奏 SetPiecePlayMode(1,0,1920) 一致)。 */
|
||||||
|
#define FREE_BEAT_TICKS 480u
|
||||||
|
#define FREE_PIECE_TICKS 1920u
|
||||||
|
|
||||||
|
static uint8_t s_free_even_stop_arm = 0;
|
||||||
|
static uint64_t s_free_even_stop_tick = 0;
|
||||||
|
static int s_free_even_stop_beat = 2; /* 目标偶拍 2 或 4 */
|
||||||
|
static uint8_t s_free_even_seen_target = 0;
|
||||||
|
|
||||||
|
static void FreeMode_CancelEvenBeatStop(void)
|
||||||
|
{
|
||||||
|
s_free_even_stop_arm = 0;
|
||||||
|
s_free_even_stop_tick = 0;
|
||||||
|
s_free_even_stop_beat = 2;
|
||||||
|
s_free_even_seen_target = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 再次按住指板:取消待停并恢复 piece 循环 */
|
||||||
|
static void FreeMode_ResumePieceLoop(void)
|
||||||
|
{
|
||||||
|
if (!s_free_even_stop_arm)
|
||||||
|
return;
|
||||||
|
FreeMode_CancelEvenBeatStop();
|
||||||
|
if (StartFlag && mGuiData[GUI_TAB_INDEX].Current == 2 &&
|
||||||
|
!mGuiData[GUI_AUTOBAND_SW].Current)
|
||||||
|
{
|
||||||
|
AutoBandTop1_SetPiecePlayMode(1, 0, FREE_PIECE_TICKS);
|
||||||
|
AutoBandTop1_SetLoopMode(0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FreeMode_ArmEvenBeatStop(void)
|
||||||
|
{
|
||||||
|
uint64_t play;
|
||||||
|
int beat;
|
||||||
|
int target;
|
||||||
|
|
||||||
|
if (!StartFlag)
|
||||||
|
{
|
||||||
|
FreeMode_CancelEvenBeatStop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
play = AutoBandTop1_GetCurrentPlayTick();
|
||||||
|
beat = AutoBandTop1_GetCurrentBeat();
|
||||||
|
if (beat < 1)
|
||||||
|
beat = 1;
|
||||||
|
/* 拍1→2,拍2→2,拍3→4,拍4→4 */
|
||||||
|
target = ((beat + 1) / 2) * 2;
|
||||||
|
s_free_even_stop_beat = target;
|
||||||
|
s_free_even_seen_target = (beat >= target) ? 1u : 0u;
|
||||||
|
/* ((beat0/2)+1)*2*480 → 拍1/2→960,拍3/4→1920,跨小节同理 */
|
||||||
|
s_free_even_stop_tick =
|
||||||
|
((play / FREE_BEAT_TICKS) / 2ull + 1ull) * 2ull * (uint64_t)FREE_BEAT_TICKS;
|
||||||
|
s_free_even_stop_arm = 1;
|
||||||
|
|
||||||
|
/* 禁循环并裁 piece,库播到 stop tick 自停;Poll 作兜底 */
|
||||||
|
AutoBandTop1_SetLoopMode(0, 0);
|
||||||
|
if (s_free_even_stop_tick <= 0xFFFFFFFFull)
|
||||||
|
AutoBandTop1_SetPiecePlayMode(1, 0, (uint32_t)s_free_even_stop_tick);
|
||||||
|
|
||||||
|
LOG_I("pick", "free even-stop arm beat=%d target=%d play=%u stop=%u",
|
||||||
|
beat, target, (unsigned)play, (unsigned)s_free_even_stop_tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeMode_PollEvenBeatStop(void)
|
||||||
|
{
|
||||||
|
int beat;
|
||||||
|
uint8_t tick_done;
|
||||||
|
uint8_t beat_done;
|
||||||
|
|
||||||
|
if (!s_free_even_stop_arm)
|
||||||
|
return;
|
||||||
|
if (PressFlag || mGuiData[GUI_TAB_INDEX].Current != 2 || !StartFlag)
|
||||||
|
{
|
||||||
|
FreeMode_CancelEvenBeatStop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
beat = AutoBandTop1_GetCurrentBeat();
|
||||||
|
if (beat == s_free_even_stop_beat)
|
||||||
|
s_free_even_seen_target = 1;
|
||||||
|
/* 已到达目标偶拍后离开该拍 = 该拍播完;或 play tick 到点 */
|
||||||
|
beat_done = (s_free_even_seen_target && beat != s_free_even_stop_beat && beat != 0) ? 1u : 0u;
|
||||||
|
tick_done = (AutoBandTop1_GetCurrentPlayTick() >= s_free_even_stop_tick) ? 1u : 0u;
|
||||||
|
|
||||||
|
if (tick_done || beat_done)
|
||||||
|
{
|
||||||
|
FreeMode_CancelEvenBeatStop();
|
||||||
|
KEY_ID_1629 = 0;
|
||||||
|
Stop_AutoBand();
|
||||||
|
LOG_I("pick", "free even-stop done beat=%d tick=%u beatDone=%u",
|
||||||
|
beat, (unsigned)tick_done, (unsigned)beat_done);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Stop_AutoBand()
|
void Stop_AutoBand()
|
||||||
{
|
{
|
||||||
|
FreeMode_CancelEvenBeatStop();
|
||||||
AutoBandTop1_Stop();
|
AutoBandTop1_Stop();
|
||||||
for(uint8_t i = 0;i < 16;i++)
|
for(uint8_t i = 0;i < 16;i++)
|
||||||
{
|
{
|
||||||
|
|
@ -914,10 +1012,10 @@ void TM1629_Handle(uint8_t key)
|
||||||
PressFlag = 0;
|
PressFlag = 0;
|
||||||
if(mGuiData[GUI_TAB_INDEX].Current == 2)
|
if(mGuiData[GUI_TAB_INDEX].Current == 2)
|
||||||
{
|
{
|
||||||
/* 普通:松手立即结束当前和弦伴奏 */
|
/* 普通:松手对齐到偶拍末再停(拍1→拍2末,拍3→拍4末) */
|
||||||
KEY_ID_1629 = 0;
|
KEY_ID_1629 = 0;
|
||||||
if (StartFlag)
|
if (StartFlag)
|
||||||
Stop_AutoBand();
|
FreeMode_ArmEvenBeatStop();
|
||||||
}
|
}
|
||||||
else if(mGuiData[GUI_TAB_INDEX].Current == 0)
|
else if(mGuiData[GUI_TAB_INDEX].Current == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -940,7 +1038,8 @@ void TM1629_Handle(uint8_t key)
|
||||||
}
|
}
|
||||||
else if(mGuiData[GUI_TAB_INDEX].Current == 2)
|
else if(mGuiData[GUI_TAB_INDEX].Current == 2)
|
||||||
{
|
{
|
||||||
/* 普通:按住指板,等待拨片起奏当前和弦 */
|
/* 普通:按住指板;若正在偶拍收束则恢复循环续奏 */
|
||||||
|
FreeMode_ResumePieceLoop();
|
||||||
PressFlag = 1;
|
PressFlag = 1;
|
||||||
}
|
}
|
||||||
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 */
|
||||||
|
|
@ -1637,6 +1736,7 @@ void Read_Cur_Measure()
|
||||||
(tab == 3 && (last == 0 || last == 2));
|
(tab == 3 && (last == 0 || last == 2));
|
||||||
|
|
||||||
Band_TrackPlayTick();
|
Band_TrackPlayTick();
|
||||||
|
FreeMode_PollEvenBeatStop();
|
||||||
|
|
||||||
/* 尾奏中保持全绿,不刷新和弦走向红灯 */
|
/* 尾奏中保持全绿,不刷新和弦走向红灯 */
|
||||||
if (loop_light_ok && StartFlag && !s_outro_led_all_green)
|
if (loop_light_ok && StartFlag && !s_outro_led_all_green)
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,8 @@ extern void (*CurrUIProcress)(DisplayTaskMessage_Type xEvent);
|
||||||
|
|
||||||
|
|
||||||
void Stop_AutoBand();
|
void Stop_AutoBand();
|
||||||
|
/* 普通模式:松手后偶拍收束轮询(由 Read_Cur_Measure 调用) */
|
||||||
|
void FreeMode_PollEvenBeatStop(void);
|
||||||
/* 当前调一级大和弦(把位1 + maj);开机/进模式/前奏/拨片兜底共用 */
|
/* 当前调一级大和弦(把位1 + maj);开机/进模式/前奏/拨片兜底共用 */
|
||||||
void Accomp_ApplyDefaultIChord(void);
|
void Accomp_ApplyDefaultIChord(void);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue