K1Guitar/UI/UI_Mixer.c

252 lines
8.4 KiB
C
Raw Permalink 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"
extern const Touch_AreaTypeDef *pCurrentTouch_Area;
static int8_t s_mixer_focus = -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-06圆钮定位半径 = 色条半宽;填充略大以盖住柱端抗锯齿白边(夹紧不画出柱外) */
#define MIXER_KNOB_R 15
#define MIXER_KNOB_FILL_R 16
#define MIXER_TRACK_HALF_W 15
/* 与柱端半圆同形的实心圆钮:顶/底档位与色条圆角完美贴合,无虚线白边 */
static void DrawMixerKnob(uint16_t cx, uint16_t cy)
{
int16_t dy;
int32_t r2 = (int32_t)MIXER_KNOB_FILL_R * (int32_t)MIXER_KNOB_FILL_R;
for (dy = -(int16_t)MIXER_KNOB_R; dy <= (int16_t)MIXER_KNOB_R; dy++)
{
int32_t xx = r2 - (int32_t)dy * (int32_t)dy;
int16_t dx = 0;
int16_t half;
if (xx < 0)
continue;
while ((int32_t)(dx + 1) * (dx + 1) <= xx)
dx++;
half = dx;
if (half > (int16_t)MIXER_TRACK_HALF_W)
half = (int16_t)MIXER_TRACK_HALF_W;
LCD_FillByColor((uint16_t)(cx - half), (uint16_t)(cy + dy),
(uint16_t)(cx + half + 1), (uint16_t)(cy + dy + 1),
COLOR_GRAD_MID);
}
}
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_R);
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();
}
// ============================================================
// 滑块顶边 Yval0/10 时圆心落在色条底/顶半圆中心,两端对称贴合
// ============================================================
static uint16_t CalcSliderY(Fader_t *f)
{
uint16_t top_cy = (uint16_t)(f->y + MIXER_KNOB_R);
uint16_t bot_cy = (uint16_t)(f->y + f->h - 1 - MIXER_KNOB_R);
uint16_t cy = (uint16_t)(bot_cy - ((uint32_t)(bot_cy - top_cy) * f->val) / 10);
return (uint16_t)(cy - MIXER_KNOB_R);
}
int CheckTouchFader(uint16_t x, uint16_t y)
{
for (int i = 0; i < 4; i++) {
Fader_t *f = &faders[i];
if (x >= f->x - 10 && x <= f->x + f->w + 10 &&
y >= f->y && y <= f->y + f->h) {
return i;
}
}
return -1;
}
// ==================== ????? ====================
void UI_Mixer_Init(void)
{
s_mixer_focus = -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:
tx = msg.HiByte;
ty = msg.LoByte;
// 1. ?????????
fader_idx = CheckTouchFader(tx, ty);
if (fader_idx >= 0)
{
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;
}
}
ResetAutoPowerCount();
break;
case MSG_ID_EC_VOL:
/* 调音台子页无状态栏音量条(与返回键重叠);主音量已在 MainTask 下发 */
ResetAutoPowerCount();
break;
}
}