K1Guitar/UI/UI_Mixer.c

253 lines
8.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "includes.h"
#include "mixer_knob_0902.h"
extern const Touch_AreaTypeDef *pCurrentTouch_Area;
static int8_t s_mixer_focus = -1;
static int8_t s_mixer_grab = -1; /* 按下锁定的推子,松手前不换轨 */
/* 0902-06 调音台:返回 + 标题;无底栏 */
const Touch_AreaTypeDef Touch_Mixer_Areas[] = {
{ 0, 44, 0, 40, 0, 0, GUI_CANCEL, NULL },
};
#define TOUCH_BTN_NUM (sizeof(Touch_Mixer_Areas)/sizeof(Touch_AreaTypeDef))
/* 左→右 伴奏|弦|麦|麦混响;Flash 标签按内容挂接(13伴奏/14弦/15麦/16麦混响) */
static const uint32_t s_fader_label[4][3] = { /* addr, w, h */
{ UI0902_TXT_MIXER_BAND_ADDR, UI0902_TXT_MIXER_BAND_W, UI0902_TXT_MIXER_BAND_H },
{ UI0902_TXT_MIXER_GUITAR_ADDR, UI0902_TXT_MIXER_GUITAR_W, UI0902_TXT_MIXER_GUITAR_H },
{ UI0902_TXT_MIXER_MIC_ADDR, UI0902_TXT_MIXER_MIC_W, UI0902_TXT_MIXER_MIC_H },
{ UI0902_TXT_MIXER_VOCALFX_ADDR, UI0902_TXT_MIXER_VOCALFX_W, UI0902_TXT_MIXER_VOCALFX_H },
};
// ============================================================
// ????????????????????? / ?????????????
// ============================================================
void DrawFader(Fader_t *f)
{
uint16_t cx = f->x + f->w / 2;
uint16_t slider_y;
LCD_FillByColor(cx - 20, f->y, cx + 20, f->y + f->h + 30, UI0902_BG_COLOR);
LCD_WR_PIC_FROM_FLASH(cx - 15, f->y, 31, 215, UI0902_MIXER_TRACK_ADDR);
LCD_WR_PIC_FROM_FLASH_Trans(cx - s_fader_label[f->id][1] / 2, f->y + f->h + 8,
(uint16_t)s_fader_label[f->id][1], (uint16_t)s_fader_label[f->id][2],
s_fader_label[f->id][0]);
slider_y = CalcSliderY(f);
DrawFaderSlider(f, slider_y);
f->prev_slider_y = slider_y;
}
/* 四路推子写入 NVM 参数(仅 RAM;落盘由 save 调用方决定) */
static void SyncMixerFadersToNvm(void)
{
NvmParam_Type *nvm = drv_nvm_param_ptr();
nvm->param.BandVol = faders[0].val;
nvm->param.StringVol = faders[1].val;
nvm->param.MIcVol = faders[2].val;
nvm->param.MicRev = faders[3].val;
}
void DrawAllFaders(void)
{
for (int i = 0; i < 4; i++) {
DrawFader(&faders[i]);
}
SyncMixerFadersToNvm();
drv_nvm_save_to_flash();
}
/* 美工 0902-31 方圆色块 24x23;透明角贴在色条上,数字另画 */
#define MIXER_KNOB_W MIXER_KNOB_ART_W
#define MIXER_KNOB_H MIXER_KNOB_ART_H
static void DrawMixerKnob(uint16_t cx, uint16_t cy)
{
uint16_t x = (uint16_t)(cx - MIXER_KNOB_W / 2);
uint16_t y = (uint16_t)(cy - MIXER_KNOB_H / 2);
LCD_WR_PIC_Trans(x, y, MIXER_KNOB_W, MIXER_KNOB_H, gImage_MixerKnob_24x23, BLACK);
}
static void DrawFaderSlider(Fader_t *f, uint16_t slider_y)
{
uint16_t cx = f->x + f->w / 2;
uint16_t ly = f->y + f->h + 8;
uint16_t cy = (uint16_t)(slider_y + MIXER_KNOB_H / 2);
char buf[8];
DrawMixerKnob(cx, cy);
sprintf(buf, "%d", f->val);
LCD_ShowString_AutoAlign((uint16_t)(cx - 10), (uint16_t)(cx + 10),
(uint16_t)(cy - 5),
(uint8_t*)buf, LCD_ALIGN_CENTER, WHITE, COLOR_GRAD_MID, 0, 11);
LCD_FillByColor(cx - 15, ly + 17, cx + 15, ly + 19, UI0902_BG_COLOR);
if (s_mixer_focus == (int8_t)f->id)
LCD_FillByColor(cx - 15, ly + 17, cx + 15, ly + 19, COLOR_GRAD_MID);
}
// ============================================================
// ???????????????????????????????????? Flash ????
// ============================================================
static void UpdateFaderSlider(Fader_t *f)
{
uint16_t cx = f->x + f->w / 2;
uint16_t new_y = CalcSliderY(f);
if (f->prev_slider_y == new_y) return;
LCD_WR_PIC_FROM_FLASH(cx - 15, f->y, 31, 215, UI0902_MIXER_TRACK_ADDR);
DrawFaderSlider(f, new_y);
f->prev_slider_y = new_y;
}
void UpdateFaderByTouch(int idx, uint16_t y)
{
uint8_t val_127;
uint8_t STR_val;
if (idx < 0 || idx > 3) return;
Fader_t *f = &faders[idx];
if (s_mixer_focus != (int8_t)idx)
{
int8_t prev = s_mixer_focus;
s_mixer_focus = (int8_t)idx;
if (prev >= 0 && prev <= 3)
DrawFaderSlider(&faders[prev], faders[prev].prev_slider_y);
}
uint16_t y_min = f->y;
uint16_t y_max = f->y + f->h;
if (y < y_min + 8) {
f->val = 10;
}
else if (y > y_max - 8) {
f->val = 0;
}
else {
int32_t val_raw = 10 - ((int32_t)(y - y_min) * 10) / (y_max - y_min);
if(val_raw < 0) val_raw = 0;
if(val_raw > 10) val_raw = 10;
f->val = val_raw;
}
UpdateFaderSlider(f);
DrawFaderSlider(f, f->prev_slider_y);
switch(idx) {
case 0:
val_127 = (f->val * 127) / 10;
SendVolumeChangeMidiEvent(1,val_127);
SendVolumeChangeMidiEvent(2,val_127);
SendVolumeChangeMidiEvent(3,val_127);
SendVolumeChangeMidiEvent(4,val_127);
SendVolumeChangeMidiEvent(5,val_127);
SendVolumeChangeMidiEvent(6,val_127);
SendVolumeChangeMidiEvent(7,val_127);
SendVolumeChangeMidiEvent(8,val_127);
SendVolumeChangeMidiEvent(9,val_127);
SendVolumeChangeMidiEvent(10,val_127);
SendVolumeChangeMidiEvent(11,val_127);
SendVolumeChangeMidiEvent(12,val_127);
SendVolumeChangeMidiEvent(13,val_127);
SendVolumeChangeMidiEvent(14,val_127);
SendVolumeChangeMidiEvent(15,val_127);
break;
case 1:
STR_val = (f->val * 127) / 10;
SendVolumeChangeMidiEvent(0,STR_val);
break;
case 2:
AW816_Set_Volume(MIC_VOL_MAP[f->val]);
break;
case 3:
AW816_Set_Reverb(f->val * 10);
break;
}
/* 即时生效同时更新 NVM 镜像;返回/关机时落盘 */
SyncMixerFadersToNvm();
}
// ============================================================
// 滑块顶边 Y:0/10 档方圆贴色条底/顶,不超出柱身
// ============================================================
static uint16_t CalcSliderY(Fader_t *f)
{
uint16_t half = (uint16_t)(MIXER_KNOB_H / 2);
uint16_t top_cy = (uint16_t)(f->y + half);
uint16_t bot_cy = (uint16_t)(f->y + f->h - (MIXER_KNOB_H - half));
uint16_t cy = (uint16_t)(bot_cy - ((uint32_t)(bot_cy - top_cy) * f->val) / 10);
return (uint16_t)(cy - half);
}
int CheckTouchFader(uint16_t x, uint16_t y)
{
for (int i = 0; i < 4; i++) {
Fader_t *f = &faders[i];
/* 热区不超过轨宽+两侧小余量,避免与邻轨重叠误触 */
if (x >= f->x - 4 && x <= f->x + f->w + 4 &&
y >= f->y && y <= f->y + f->h) {
return i;
}
}
return -1;
}
// ==================== ????? ====================
void UI_Mixer_Init(void)
{
s_mixer_focus = -1;
s_mixer_grab = -1;
UI_ClearFocus();
LCD_FillByColor(0, 0, 240, 320, UI0902_BG_COLOR);
UI_DrawSubPageHeader((const uint8_t*)"\xB5\xF7\xD2\xF4\xCC\xA8");
DrawAllFaders();
pCurrentTouch_Area = Touch_Mixer_Areas;
}
// ==================== ???????? ====================
void UI_Mixer_Process(DisplayTaskMessage_Type msg)
{
uint16_t tx,ty;
int fader_idx;
switch(msg.MessageType)
{
case MSG_ID_TOUCH:
/* 推子拖动会 early-return:须先复位,否则调音台操作无法打断自动关机 */
ResetAutoPowerCount();
tx = msg.HiByte;
ty = msg.LoByte;
/* ID=0:抬起,解开推子锁定 */
if (msg.ID == 0)
{
s_mixer_grab = -1;
break;
}
if (s_mixer_grab >= 0)
{
UpdateFaderByTouch(s_mixer_grab, ty);
return;
}
fader_idx = CheckTouchFader(tx, ty);
if (fader_idx >= 0)
{
s_mixer_grab = (int8_t)fader_idx;
UpdateFaderByTouch(fader_idx, ty);
return;
}
// 2. 返回 → 设置入口
for(uint8_t i=0; i<TOUCH_BTN_NUM; i++)
{
if( tx >= Touch_Mixer_Areas[i].x_min && tx <= Touch_Mixer_Areas[i].x_max &&
ty >= Touch_Mixer_Areas[i].y_min && ty <= Touch_Mixer_Areas[i].y_max )
{
if (Touch_Mixer_Areas[i].ID == GUI_CANCEL) {
SyncMixerFadersToNvm();
drv_nvm_save_to_flash();
MenuPage_SystemSetting_Proc();
}
break;
}
}
break;
case MSG_ID_EC_VOL:
/* 调音台子页无状态栏音量条(与返回键重叠);主音量已在 MainTask 下发 */
ResetAutoPowerCount();
break;
}
}