diff --git a/Global/Global.c b/Global/Global.c index 75f4bf3..47d9984 100644 --- a/Global/Global.c +++ b/Global/Global.c @@ -111,7 +111,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,48}; /* major.minor.patch — 0.2.48: 万能拨片只启动;按键板热插拔后 LED 继续亮 */ +const uint8_t Version[3] = {0,2,49}; /* major.minor.patch — 0.2.49: 曲目默认 BPM;出厂项与关机记忆 */ uint8_t Led = 8; bool PressFlag = 0; @@ -236,9 +236,8 @@ void System_PowerOn(void) /* 软关机不复位 MCU:清掉上次会话演奏状态,默认当前调一级大和弦(C 调=do mi sol) */ StartFlag = 0; InModeFlag = false; /* 停在模式选择,禁止拨片/侧面键起奏 */ - /* 弦音色不记忆。节奏类型留在 RAM/NVM,软开关机后仍是上次选择 */ - mGuiData[GUI_TIMBRE_SELECT].Current = TIMBRE_BOOT_SLOT; - drv_nvm_param_ptr()->param.Timbre = TIMBRE_BOOT_SLOT; + /* 弦音色、移调跨开关机保留。节奏/曲目/走向/段落/蓝牙/BPM 每次开机回默认 */ + Session_ApplyPowerOnDefaults(); Accomp_ApplyDefaultIChord(); app_tm1629_reset_key_state(); s_pwr_rails_cut = 0u; diff --git a/UI/UI_FreeMode.c b/UI/UI_FreeMode.c index 29f139d..207e59f 100644 --- a/UI/UI_FreeMode.c +++ b/UI/UI_FreeMode.c @@ -103,11 +103,6 @@ void UI_FreeMode_Process(DisplayTaskMessage_Type msg) { Refresh_Transpose(&UI_Label[GUI_SPEED], &mGuiData[GUI_SPEED]); - if(nvm->param.BPM != mGuiData[GUI_SPEED].Current) - { - nvm->param.BPM = mGuiData[GUI_SPEED].Current; - } - uint8_t Speed[6] = {0xF0, 0x51, 0x03, 0x00, 0x00, 0xF7}; Speed[3] = mGuiData[GUI_SPEED].Current / 128; Speed[4] = mGuiData[GUI_SPEED].Current % 128; diff --git a/UI/UI_SongMode.c b/UI/UI_SongMode.c index 7e5bc1f..0ca4441 100644 --- a/UI/UI_SongMode.c +++ b/UI/UI_SongMode.c @@ -152,11 +152,8 @@ void Touch_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex,uint8_t value) Speed[4] = mGuiData[ID].Current % 128; USART4_SendData(Speed,sizeof(Speed)); - if(nvm->param.BPM != mGuiData[ID].Current) - { - nvm->param.BPM = mGuiData[ID].Current; - } - AutoBandTop1_ChangeBPM(mGuiData[ID].Current); // AutoBand 模块未加入工程 + /* 同一曲目内的手调速度只在本次开机有效 */ + AutoBandTop1_ChangeBPM(mGuiData[ID].Current); } break; @@ -197,6 +194,7 @@ void Touch_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex,uint8_t value) tab, mGuiData[GUI_AUTOBAND_SW].Current, AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "?", (unsigned)ADDRESS); + TrackBpm_OnPresetLoaded(); if (tab == 0) nvm->param.Param3 = ParamGuiData[ALL_MODE_PARAM].Current; @@ -410,11 +408,7 @@ void UI_SongMode_Process(DisplayTaskMessage_Type msg) if (!UI_SetFocus(GUI_SPEED)) Refresh_Transpose(&UI_Label[GUI_SPEED], &mGuiData[GUI_SPEED]); AutoBandTop1_ChangeBPM(mGuiData[GUI_SPEED].Current); - if(nvm->param.BPM != mGuiData[GUI_SPEED].Current) - { - nvm->param.BPM = mGuiData[GUI_SPEED].Current; - } - + Speed[3] = mGuiData[GUI_SPEED].Current / 128; Speed[4] = mGuiData[GUI_SPEED].Current % 128; USART4_SendData(Speed,sizeof(Speed)); @@ -469,10 +463,6 @@ void UI_SongMode_Process(DisplayTaskMessage_Type msg) { Refresh_Transpose(&UI_Label[GUI_SPEED], &mGuiData[GUI_SPEED]); - if(nvm->param.BPM != mGuiData[GUI_SPEED].Current) - { - nvm->param.BPM = mGuiData[GUI_SPEED].Current; - } uint8_t Speed[6] = {0xF0, 0x51, 0x03, 0x00, 0x00, 0xF7}; Speed[3] = mGuiData[GUI_SPEED].Current / 128; Speed[4] = mGuiData[GUI_SPEED].Current % 128; diff --git a/UI/UI_global.c b/UI/UI_global.c index 7515840..66cf8b4 100644 --- a/UI/UI_global.c +++ b/UI/UI_global.c @@ -179,6 +179,127 @@ void UI_ApplyToneAddress(void) (ADDRESS == expect) ? "OK" : "MISMATCH"); } +/* Doc/默认出厂设置:万能三条都是 92;节奏 31 条。第 20 条打榜摇滚乐 = 91。 + * 本地曲目不在表内,切过去不改当前速度。 */ +static const uint16_t kRhythmBpm[31] = { + 79, 105, 115, 89, 61, 78, 74, 111, 60, 99, + 65, 76, 75, 86, 72, 90, 92, 125, 94, 91, + 82, 115, 92, 86, 127, 86, 59, 112, 92, 86, 69 +}; + +static uint8_t s_track_valid; +static uint8_t s_track_tab; +static uint8_t s_track_local; +static uint16_t s_track_idx; + +static void Track_Read(uint8_t *tab, uint8_t *local, uint16_t *idx) +{ + *tab = (uint8_t)mGuiData[GUI_TAB_INDEX].Current; + if (*tab == 0) + { + *local = 0; + *idx = ParamGuiData[ALL_MODE_PARAM].Current; + } + else if (mGuiData[GUI_AUTOBAND_SW].Current) + { + *local = 1; + *idx = ParamGuiData[EXPRESS_MODE_PARAM].Current; + } + else + { + *local = 0; + *idx = ParamGuiData[SONG_MODE_PARAM].Current; + } +} + +static uint8_t Track_LookupBpm(uint8_t tab, uint8_t local, uint16_t idx, uint16_t *bpm) +{ + if (tab == 0) + { + *bpm = 92; + return 1; + } + if (local) + return 0; + if (idx >= (uint16_t)(sizeof(kRhythmBpm) / sizeof(kRhythmBpm[0]))) + return 0; + *bpm = kRhythmBpm[idx]; + return 1; +} + +void TrackBpm_Invalidate(void) +{ + s_track_valid = 0; +} + +uint8_t TrackBpm_SyncGui(void) +{ + uint8_t tab; + uint8_t local; + uint16_t idx; + uint16_t bpm; + + Track_Read(&tab, &local, &idx); + if (s_track_valid && s_track_tab == tab && s_track_local == local && s_track_idx == idx) + return 0; + s_track_valid = 1; + s_track_tab = tab; + s_track_local = local; + s_track_idx = idx; + if (!Track_LookupBpm(tab, local, idx, &bpm)) + return 0; + if (mGuiData[GUI_SPEED].Current != bpm) + { + mGuiData[GUI_SPEED].Current = bpm; + LOG_I("BPM", "track bpm=%u tab=%u local=%u idx=%u", + (unsigned)bpm, (unsigned)tab, (unsigned)local, (unsigned)idx); + } + return 1; +} + +uint16_t TrackBpm_Peek(void) +{ + uint8_t tab; + uint8_t local; + uint16_t idx; + uint16_t bpm; + + Track_Read(&tab, &local, &idx); + /* 还是这一首:手调速度保持,不要被默认表盖掉 */ + if (s_track_valid && s_track_tab == tab && s_track_local == local && s_track_idx == idx) + return mGuiData[GUI_SPEED].Current; + if (!Track_LookupBpm(tab, local, idx, &bpm)) + return mGuiData[GUI_SPEED].Current; + return bpm; +} + +void TrackBpm_OnPresetLoaded(void) +{ + uint8_t changed = TrackBpm_SyncGui(); + AutoBandTop1_ChangeBPM((int)mGuiData[GUI_SPEED].Current); + if (changed && CurrUIProcress == UI_SongMode_Process) + Refresh_Transpose(&UI_Label[GUI_SPEED], &mGuiData[GUI_SPEED]); +} + +void Session_ApplyPowerOnDefaults(void) +{ + NvmParam_Type *nvm = drv_nvm_param_ptr(); + + nvm->param.BluetoothSW = 1; + nvm->param.Param1 = 0; + nvm->param.Param2 = 0; + nvm->param.Param3 = 0; + mGuiData[GUI_BL_SW].Current = 1; + mGuiData[GUI_PLAY_SECTION].Current = 0; + mGuiData[GUI_AUTOBAND_SW].Current = 0; + ParamGuiData[SONG_MODE_PARAM].Current = 0; + ParamGuiData[EXPRESS_MODE_PARAM].Current = 0; + ParamGuiData[ALL_MODE_PARAM].Current = 0; + TrackBpm_Invalidate(); + TrackBpm_SyncGui(); + nvm->param.BPM = mGuiData[GUI_SPEED].Current; +} + void UI_ReloadTonePreset(void) { UI_ApplyToneAddress(); @@ -205,6 +326,7 @@ void UI_ReloadTonePreset(void) AutoBandTop1_GetPresetName() ? AutoBandTop1_GetPresetName() : "?", (unsigned)ADDRESS, (unsigned)EXTFLASH_BIN3_UNIVERSAL_ADDR); } + TrackBpm_OnPresetLoaded(); return; } /* 普通/专业:本地曲目或节奏类型 */ @@ -231,6 +353,7 @@ void UI_ReloadTonePreset(void) if (bin_n != LOCAL_SONG_COUNT) LOG_W("tone", "local song count csv=%d bin=%d", LOCAL_SONG_COUNT, bin_n); } + TrackBpm_OnPresetLoaded(); return; } { @@ -243,6 +366,7 @@ void UI_ReloadTonePreset(void) (ADDRESS == EXTFLASH_BIN1_RHYTHM_ADDR) ? "OK" : "MISMATCH"); (void)ret; } + TrackBpm_OnPresetLoaded(); } static uint8_t s_ui_focus_id = UI_FOCUS_NONE; @@ -1228,6 +1352,7 @@ void RestoreSetting(void) drv_nvm_load_default_calibration_static_value(nvm, 1); mGuiData[GUI_PLAY_SECTION].Current = 0; + mGuiData[GUI_AUTOBAND_SW].Current = 0; /* 出厂默认蓝牙开(已由 static_value 写入 NVM/GUI) */ mGuiData[GUI_BL_SW].Current = 1; @@ -1237,6 +1362,11 @@ void RestoreSetting(void) mGuiData_SystemSETTING[GUI_USB_MODE].Current = NVM_USB_MIDI; BSP_BlueToothPowerEnable(1); + /* 出厂后的曲目是当前模式下的第 1 条,BPM 跟那一条 */ + TrackBpm_Invalidate(); + TrackBpm_SyncGui(); + nvm->param.BPM = mGuiData[GUI_SPEED].Current; + ApplyAutoCloseIndex(mGuiData_SystemSETTING[GUI_AUTOCLOSE].Current); /* 音色 / 音量 / 混响等到 DSP */ diff --git a/UI/UI_global.h b/UI/UI_global.h index 8d56568..327a49c 100644 --- a/UI/UI_global.h +++ b/UI/UI_global.h @@ -288,4 +288,11 @@ extern void UI_DrawSystemSetHeader(void); /* 节奏类型→1.bin / 本地曲目→2.bin / 万能→3.bin */ extern void UI_ApplyToneAddress(void); extern void UI_ReloadTonePreset(void); +/* 开机/切曲目:万能与节奏套默认 BPM;本地曲目不改速度。键未变则不覆盖手调 */ +void TrackBpm_Invalidate(void); +uint8_t TrackBpm_SyncGui(void); +uint16_t TrackBpm_Peek(void); +void TrackBpm_OnPresetLoaded(void); +/* 每次开机:蓝牙开、节奏/曲目/走向/段落回默认,并套当前曲目 BPM */ +void Session_ApplyPowerOnDefaults(void); #endif diff --git a/driver/drv_nvm.c b/driver/drv_nvm.c index be66753..005867c 100644 --- a/driver/drv_nvm.c +++ b/driver/drv_nvm.c @@ -199,7 +199,7 @@ void drv_nvm_load_default_calibration_static_value(NvmParam_Type * pData, uint8 if(reset_open_status) { - pData->param.BPM = 100; + pData->param.BPM = 92; /* 万能默认;进节奏后由曲目表覆盖 */ pData->param.Timbre = TIMBRE_BOOT_SLOT; pData->param.BandVol = 7; pData->param.StringVol = 7; @@ -215,9 +215,26 @@ void drv_nvm_load_default_calibration_static_value(NvmParam_Type * pData, uint8 pData->param.Language = NVM_LANG_CN; pData->param.UsbMode = NVM_USB_MIDI; } - mGuiData[GUI_SPEED].Current = pData->param.BPM; - /* 弦音色不跨开关机记忆,冷启动显示第 1 项,Bank1 Program 24 */ - pData->param.Timbre = TIMBRE_BOOT_SLOT; + else + { + /* 不记忆:忽略 Flash 里上次的蓝牙、节奏、曲目、走向、BPM */ + pData->param.BluetoothSW = 1; + pData->param.Param1 = 0; + pData->param.Param2 = 0; + pData->param.Param3 = 0; + } + if (pData->param.Timbre > 4) + pData->param.Timbre = TIMBRE_BOOT_SLOT; + if (pData->param.Transpose > 11) + pData->param.Transpose = 0; + if (pData->param.BandVol > 10) + pData->param.BandVol = 7; + if (pData->param.StringVol > 10) + pData->param.StringVol = 7; + if (pData->param.MIcVol > 10) + pData->param.MIcVol = 7; + if (pData->param.MicRev > 10) + pData->param.MicRev = 7; mGuiData[GUI_TIMBRE_SELECT].Current = pData->param.Timbre; mGuiData[GUI_TRANSPOSE].Current = pData->param.Transpose; faders[0].val = pData->param.BandVol; @@ -252,6 +269,10 @@ void drv_nvm_load_default_calibration_static_value(NvmParam_Type * pData, uint8 ParamGuiData[SONG_MODE_PARAM].Current = pData->param.Param1; ParamGuiData[EXPRESS_MODE_PARAM].Current = pData->param.Param2; ParamGuiData[ALL_MODE_PARAM].Current = pData->param.Param3; + /* BPM 跟当前曲目,不恢复 Flash 里的旧速度 */ + TrackBpm_Invalidate(); + TrackBpm_SyncGui(); + pData->param.BPM = mGuiData[GUI_SPEED].Current; // mGuiData[GUI_SPEED].Current = pData->param.ReverbVolume; // mGuiData[GUI_SPEED].Current = pData->param.WirelessSW; diff --git a/protocol/bl_uart_parse.c b/protocol/bl_uart_parse.c index e3e0f03..723a271 100644 --- a/protocol/bl_uart_parse.c +++ b/protocol/bl_uart_parse.c @@ -430,7 +430,6 @@ static void handleBPM(uint8_t *data) case 1: { - NvmParam_Type * nvm = drv_nvm_param_ptr(); uint16_t new_val = Calc_BPM(data[5],data[6]); // ���ֵû�䣬ֱ���˳�����ˢ�� @@ -440,11 +439,7 @@ static void handleBPM(uint8_t *data) } mGuiData[GUI_SPEED].Current = new_val; MainTask_Sendmsg(MSG_ID_BLE_UI_REFRESH, GUI_SPEED, 0, 0); - if(nvm->param.BPM != mGuiData[GUI_SPEED].Current) - { - nvm->param.BPM = mGuiData[GUI_SPEED].Current; - drv_nvm_save_to_flash(); - } + /* 手调 BPM 不写入下次开机 */ AutoBandTop1_ChangeBPM(mGuiData[GUI_SPEED].Current); } break; @@ -802,6 +797,11 @@ static void handleRhythmStyle(uint8_t *data) else nvm->param.Param1 = ParamGuiData[SONG_MODE_PARAM].Current; } + /* 回复用新曲目的默认 BPM。键留给 UI 任务换库后再提交,避免屏上不刷新 */ + { + uint16_t track_bpm = TrackBpm_Peek(); + mGuiData[GUI_SPEED].Current = track_bpm; + } /* doc: single-byte bpm; clamp >127 (App should read exact bpm via 03 06) */ resp[5] = (mGuiData[GUI_SPEED].Current > 0x7F) ? 0x7F : (uint8_t)mGuiData[GUI_SPEED].Current;