Compare commits
3 Commits
295a2a6fa3
...
439ccf439d
| Author | SHA1 | Date |
|---|---|---|
|
|
439ccf439d | |
|
|
2d62e1e41a | |
|
|
4aad989263 |
|
|
@ -303,6 +303,14 @@ void app_adc_sync_volume(uint16_t val)
|
|||
app_adc_volume_map_level(val);
|
||||
}
|
||||
|
||||
/* 取当前主音量(复用扫描任务维护的最近一次有效值)。
|
||||
* 模拟开关同一时刻只选中一路,离开扫描上下文直接重读 ADC 会串到
|
||||
* 其它通道,故统一走 vol_last;未初始化(0xFFFF)时按静音兜底 */
|
||||
uint8_t app_adc_get_volume(void)
|
||||
{
|
||||
return (vol_last > 127) ? 0 : (uint8_t)vol_last;
|
||||
}
|
||||
|
||||
static void app_adc_volume_process(void)
|
||||
{
|
||||
uint16_t val = ADC_ReadChannel(ADC_CHANNEL_1)>>5;
|
||||
|
|
|
|||
|
|
@ -27,4 +27,6 @@ void app_adc_in1_scan_part(uint8_t channel);
|
|||
bool app_adc_usb_is_plugged(void);
|
||||
/* 开机/主动采样后同步 vol_last 与 level,避免扫描任务误触发或跳变 */
|
||||
void app_adc_sync_volume(uint16_t val);
|
||||
/* 取当前主音量(0~127),供 MasterVolume_Reapply 等重发场景使用 */
|
||||
uint8_t app_adc_get_volume(void);
|
||||
#endif
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
static uint8_t key_last = KEY_NONE;
|
||||
|
||||
|
||||
/* LED 期望颜色缓存:索引 = LedNum_TypeDef(0~7),COLOR_OTHER 表示灭 */
|
||||
/* LED ??????????¹×???? = LedNum_TypeDef??0~7????COLOR_OTHER ????? */
|
||||
//static LedColor_TypeDef led_cache[8] = {
|
||||
// COLOR_OTHER, COLOR_OTHER, COLOR_OTHER, COLOR_OTHER,
|
||||
// COLOR_OTHER, COLOR_OTHER, COLOR_OTHER, COLOR_OTHER
|
||||
|
|
@ -31,7 +31,12 @@ uint8_t app_tm1629_Scan_Key(void)
|
|||
if(key != key_last)
|
||||
{
|
||||
key_last = key;
|
||||
LOG_I("KEY", "tm1629 key=%u", (unsigned)key);
|
||||
if(key >= 1 && key <= 21)
|
||||
LOG_I("KEY", "tm1629 key=%u pitch=%u type=%u", (unsigned)key,
|
||||
(unsigned)chord_type_index_map[key].PitchOffset,
|
||||
(unsigned)chord_type_index_map[key].type);
|
||||
else
|
||||
LOG_I("KEY", "tm1629 key=%u", (unsigned)key);
|
||||
TM1629_Handle(key);
|
||||
return key;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -460,6 +460,16 @@ void Send_volume(uint8_t vol)
|
|||
SendMidiDataToDreamDSP(mMasterSysExVolume,12);
|
||||
}
|
||||
|
||||
/* 重发当前主音量:开机补发 / 进模式主页 / 开始播放前调用。
|
||||
* Dream 上电早期可能丢 SysEx,丢失后旋钮不动就不再重发,
|
||||
* 会出现"图标低音量、实际音量大";在关键时机重发可自愈 */
|
||||
void MasterVolume_Reapply(void)
|
||||
{
|
||||
uint8_t vol = app_adc_get_volume();
|
||||
app_adc_sync_volume(vol); /* 兜底刷新 level,保证图标与下发值一致 */
|
||||
Send_volume(vol);
|
||||
}
|
||||
|
||||
void Accomp_UpdatePlayingChord(void)
|
||||
{
|
||||
uint8_t midi_note_buff[4] = {0,};
|
||||
|
|
@ -494,6 +504,8 @@ void ADC_IN1_KEY_Handle(uint8_t key,bool on)
|
|||
case 1: AutoBandTop1_Postamble(0); break;
|
||||
case 2: AutoBandTop1_Postamble(1); break;
|
||||
}
|
||||
/* 前奏/尾奏起奏前补发主音量,保证与图标一致 */
|
||||
MasterVolume_Reapply();
|
||||
//AutoBandTop1_Start();
|
||||
AutoBandTop1_SyncStart();
|
||||
wk_delay_ms(50);
|
||||
|
|
@ -761,6 +773,10 @@ void Pick_Handle()
|
|||
note_cnt = GetChordNotesByType(chord_id, chord_type_index_map[chord_id].type, midi_note_buff);
|
||||
Return_Light_buff(KEY_ID_1629);
|
||||
|
||||
/* 首次起奏前补发主音量:防开机 SysEx 丢失后"图标低、实际大" */
|
||||
if (StartFlag == 0)
|
||||
MasterVolume_Reapply();
|
||||
|
||||
switch(mGuiData[GUI_TAB_INDEX].Current)
|
||||
{
|
||||
case 3:
|
||||
|
|
|
|||
|
|
@ -213,6 +213,7 @@ uint8_t GUI_Item_AjustValue(GUI_SWITCH * Group, int8_t Dir);
|
|||
void GUI_Item_AjustLoopValue(GUI_SWITCH * Group, int8_t Dir);
|
||||
|
||||
void Send_volume(uint8_t vol);
|
||||
void MasterVolume_Reapply(void);
|
||||
|
||||
void ADC_IN1_KEY_Handle(uint8_t key,bool on);
|
||||
void TM1617_Handle(uint8_t key);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,64 @@ static uint8_t pStoreBuffer[PRESET_BUFFER_SIZE];
|
|||
//static uint8_t* pStoreBuffer;
|
||||
#define DEFAULT_TEMPO 100
|
||||
|
||||
/* ======== 路线A:#IV 降八度拦截(音师库支持八度前的临时方案) ========
|
||||
* AutoBand 库对输入音符只做音级识别,输出音区由其内部 octaveBase 决定,
|
||||
* 固件侧在 GetChordNotesByType 里的低八度设计不可听。故在引擎输出回调处
|
||||
* 按当前和弦状态对旋律通道做条件性八度偏移;音师新库到位后整体移除。 */
|
||||
#define CHORD_OCTAVE_INTERCEPT_EN 1
|
||||
#define DRUM_CHANNEL 9 /* 鼓通道不移调 */
|
||||
|
||||
/* 当前生效的八度偏移(0 或 -12)。RAM 余量极小,不用按音符表:
|
||||
* 状态翻转瞬间先向旋律通道补 CC123(All Notes Off) 清掉旧音区的音,
|
||||
* 之后 NoteOff 统一按当前偏移还原即可,不会挂音。 */
|
||||
static int8_t s_chord_octave_shift = 0;
|
||||
|
||||
static int8_t App_Auto_TargetChordOctaveShift(void)
|
||||
{
|
||||
#if CHORD_OCTAVE_INTERCEPT_EN
|
||||
/* 与 GetChordNotesByType 的根音八度设计对齐(整段伴奏压一个八度):
|
||||
* V/VI/VII(键 13~21)根音本就在低八度(43/45/47);
|
||||
* #IV(键 10~12 + Pitch 升)整组低八度,为最低音。
|
||||
* 引擎只认音级不认八度,故在输出侧统一补 -12。 */
|
||||
if (KEY_ID_1629 >= 13 && KEY_ID_1629 <= 21)
|
||||
return -12;
|
||||
if (KEY_ID_1629 >= 10 && KEY_ID_1629 <= 12 &&
|
||||
chord_type_index_map[KEY_ID_1629].PitchOffset == 2)
|
||||
return -12;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void App_Auto_QueueAllNotesOff(void)
|
||||
{
|
||||
MidiFifoItem_t m;
|
||||
for (int ch = 0; ch < 16; ch++)
|
||||
{
|
||||
if (ch == DRUM_CHANNEL) continue;
|
||||
m.msg[0] = 0xB0 | ch;
|
||||
m.msg[1] = 123; /* CC123 All Notes Off */
|
||||
m.msg[2] = 0;
|
||||
m.msglen = 3;
|
||||
mymidififo_InQueue(&m_MidiSendFifo,&m);
|
||||
}
|
||||
}
|
||||
|
||||
/* NoteOn 路径调用:偏移状态翻转时先清旧音,再返回新偏移 */
|
||||
static int8_t App_Auto_ShiftForNoteOn(void)
|
||||
{
|
||||
int8_t target = App_Auto_TargetChordOctaveShift();
|
||||
if (target != s_chord_octave_shift)
|
||||
{
|
||||
LOG_I("OCT", "shift %d->%d chord=%u pitch=%u",
|
||||
(int)s_chord_octave_shift, (int)target,
|
||||
(unsigned)KEY_ID_1629,
|
||||
(unsigned)chord_type_index_map[KEY_ID_1629].PitchOffset);
|
||||
App_Auto_QueueAllNotesOff();
|
||||
s_chord_octave_shift = target;
|
||||
}
|
||||
return s_chord_octave_shift;
|
||||
}
|
||||
|
||||
static void Func_CallBack_ProgramChange(int channel, int program)
|
||||
{
|
||||
MidiFifoItem_t midimsg;
|
||||
|
|
@ -32,8 +90,15 @@ static void Func_CallBack_ProgramChange(int channel, int program)
|
|||
static void Func_CallBack_NoteOff(int channel,int key)
|
||||
{
|
||||
MidiFifoItem_t midimsg;
|
||||
midimsg.msg[0] = 0x80 | channel;
|
||||
midimsg.msg[1] = key;
|
||||
int out_key = key;
|
||||
if (channel != DRUM_CHANNEL && key >= 0 && key < 128)
|
||||
{
|
||||
/* 按当前偏移还原;偏移翻转瞬间的旧音已由 CC123 清掉 */
|
||||
out_key = key + s_chord_octave_shift;
|
||||
if (out_key < 0 || out_key > 127) out_key = key;
|
||||
}
|
||||
midimsg.msg[0] = 0x80 | (channel & 0x0F);
|
||||
midimsg.msg[1] = (uint8_t)out_key;
|
||||
midimsg.msg[2] = 0;
|
||||
midimsg.msglen = 3;
|
||||
mymidififo_InQueue(&m_MidiSendFifo,&midimsg);
|
||||
|
|
@ -43,9 +108,17 @@ static void Func_CallBack_NoteOff(int channel,int key)
|
|||
static void Func_CallBack_NoteOn(int channel,int key,int vel)
|
||||
{
|
||||
MidiFifoItem_t midimsg;
|
||||
midimsg.msg[0] = 0x90 | channel;
|
||||
midimsg.msg[1] = key;
|
||||
midimsg.msg[2] = vel;
|
||||
int out_key = key;
|
||||
if (channel != DRUM_CHANNEL && key >= 0 && key < 128)
|
||||
{
|
||||
int8_t shift = (vel == 0) ? s_chord_octave_shift /* vel=0 视同 NoteOff */
|
||||
: App_Auto_ShiftForNoteOn();
|
||||
out_key = key + shift;
|
||||
if (out_key < 0 || out_key > 127) out_key = key;
|
||||
}
|
||||
midimsg.msg[0] = 0x90 | (channel & 0x0F);
|
||||
midimsg.msg[1] = (uint8_t)out_key;
|
||||
midimsg.msg[2] = (uint8_t)vel;
|
||||
midimsg.msglen = 3;
|
||||
mymidififo_InQueue(&m_MidiSendFifo,&midimsg);
|
||||
|
||||
|
|
@ -135,6 +208,7 @@ static int Func_CallBack_ReadFlash(int address,int length,uint8_t* pOutput)
|
|||
//
|
||||
void App_Auto_Init(void)
|
||||
{
|
||||
LOG_I("OCT", "intercept build 20260910 en=%d", (int)CHORD_OCTAVE_INTERCEPT_EN);
|
||||
AutoBandTop1_SetPresetStoreBuffer(pStoreBuffer,PRESET_BUFFER_SIZE);
|
||||
AutoBandTop1_Init();
|
||||
AutoBandTop1_RegisterCallBack_NoteOn(Func_CallBack_NoteOn);
|
||||
|
|
|
|||
|
|
@ -163,11 +163,11 @@ void IdleProcess(DisplayTaskMessage_Type msg)
|
|||
TM1629D_UpdateDisplay(0);
|
||||
StartTouchTask();
|
||||
StartScanTask();
|
||||
/* Dream 上电稍后可能忽略首包 SysEx:再发主音量 + 调音台(保持关机前设置) */
|
||||
/* Dream 上电稍后可能忽略首包 SysEx:再发主音量 + 调音台(保持关机前设置)。
|
||||
* 此时扫描任务已启动、模拟开关在轮询,不可现场重读 ADC(会串通道),
|
||||
* 统一用 MasterVolume_Reapply 取扫描任务维护的最近一次有效音量 */
|
||||
rt_thread_mdelay(400);
|
||||
vol = ADC_ReadChannel(ADC_CHANNEL_1)>>5;
|
||||
app_adc_sync_volume(vol);
|
||||
Send_volume(vol);
|
||||
MasterVolume_Reapply();
|
||||
LoadConfig();
|
||||
Draw_Volume_Bar(UI0902_VOL_X, UI0902_VOL_Y, level, 1, WHITE, GRAY);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ void UI_Mixer_Process(DisplayTaskMessage_Type msg)
|
|||
break;
|
||||
|
||||
case MSG_ID_EC_VOL:
|
||||
Draw_Volume_Bar(UI0902_VOL_X, UI0902_VOL_Y, msg.HiByte, 1, WHITE, GRAY);
|
||||
/* 调音台子页无状态栏音量条(与返回键重叠);主音量已在 MainTask 下发 */
|
||||
ResetAutoPowerCount();
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -243,6 +243,8 @@ void Touch_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex,uint8_t value)
|
|||
AutoBandTop1_SetRunVar(mGuiData[ID].Current);
|
||||
}else
|
||||
{
|
||||
/* 触摸起奏前补发主音量,保证实际音量与图标一致 */
|
||||
MasterVolume_Reapply();
|
||||
AutoBandTop1_FillinWithIndex(value);
|
||||
AutoBandTop1_Start();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,6 +124,11 @@ void UI_SystemSet_Process(DisplayTaskMessage_Type msg)
|
|||
label_top();
|
||||
break;
|
||||
|
||||
case MSG_ID_EC_VOL:
|
||||
/* 主音量已在 MainTask 下发;此处只刷新状态栏音量条,保证与旋钮一致 */
|
||||
Draw_Volume_Bar(UI0902_VOL_X, UI0902_VOL_Y, msg.HiByte, 1, WHITE, GRAY);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ void CallUI_Idle(void) {
|
|||
|
||||
void CallUI_SongMode(void) {
|
||||
app_touch_suppress(500);
|
||||
MasterVolume_Reapply(); /* 进模式补发主音量,防开机 SysEx 丢失后实际音量与图标不符 */
|
||||
UI_SongMode_Init();
|
||||
CurrUIProcress = UI_SongMode_Process;
|
||||
app_log_set_ui_page("Song");
|
||||
|
|
@ -62,6 +63,7 @@ void CallUI_SongMode(void) {
|
|||
|
||||
void CallUI_ExpertMode(void) {
|
||||
app_touch_suppress(500);
|
||||
MasterVolume_Reapply();
|
||||
UI_ExpertMode_Init();
|
||||
// CurrUIProcress = UI_ExpertMode_Process;
|
||||
CurrUIProcress = UI_SongMode_Process;
|
||||
|
|
@ -71,6 +73,7 @@ void CallUI_ExpertMode(void) {
|
|||
|
||||
void CallUI_FreeMode(void) {
|
||||
app_touch_suppress(500);
|
||||
MasterVolume_Reapply();
|
||||
UI_FreeMode_Init();
|
||||
// CurrUIProcress = UI_FreeMode_Process;
|
||||
CurrUIProcress = UI_SongMode_Process;
|
||||
|
|
|
|||
Loading…
Reference in New Issue