fix(chord): apply fixed-key voicings from the new chord sheet
Stop adding transpose to every string and AutoBand tone. Each degree now uses the C-major source fret from the sheet, with +1 only where the sheet marks it. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
e49f5a06fc
commit
605af8f045
174
Global/Global.c
174
Global/Global.c
|
|
@ -30,6 +30,64 @@ GUI_SWITCH ParamGuiData[] =
|
|||
{ 0, 0, 2, ALL_MODE_PARAM}, // 2
|
||||
};
|
||||
|
||||
/* ======== 固定调(自动伴奏新更改和弦规则.xlsx「和弦固定调逻辑」) ========
|
||||
* 目标调各级不再整体加 GUI_TRANSPOSE,而是取 C 调「源品位」同一行;
|
||||
* 表头标 +1 的级整行再升半音(发音位置不变)。升号调(C#/Eb/F#/G#/A#)
|
||||
* 用低半音自然调的映射再全体 +1。 */
|
||||
static const int8_t FIXED_KEY_SRC[7][7] = /* [C D E F G A B][级 I..VII] → C 调源品位 0~6 */
|
||||
{
|
||||
{0, 1, 2, 3, 4, 5, 6}, /* C */
|
||||
{1, 2, 3, 4, 5, 6, 0}, /* D */
|
||||
{2, 3, 4, 5, 6, 0, 1}, /* E */
|
||||
{3, 4, 5, 5, 0, 1, 2}, /* F */
|
||||
{4, 5, 6, 0, 1, 2, 3}, /* G */
|
||||
{5, 6, 0, 1, 2, 3, 4}, /* A */
|
||||
{6, 0, 1, 2, 3, 4, 5}, /* B */
|
||||
};
|
||||
static const uint8_t FIXED_KEY_SHARP[7][7] = /* 该行相对源品位再 +1(表头「源 品 X +1」) */
|
||||
{
|
||||
{0, 0, 0, 0, 0, 0, 0}, /* C */
|
||||
{0, 0, 1, 0, 0, 0, 1}, /* D */
|
||||
{0, 1, 1, 0, 0, 1, 1}, /* E */
|
||||
{0, 0, 0, 1, 0, 0, 0}, /* F */
|
||||
{0, 0, 0, 0, 0, 0, 1}, /* G */
|
||||
{0, 0, 1, 0, 0, 1, 1}, /* A */
|
||||
{0, 1, 1, 0, 1, 1, 1}, /* B */
|
||||
};
|
||||
static const uint8_t FIXED_KEY_ROW[12] = {0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6}; /* 移调 → 自然调行 */
|
||||
static const uint8_t FIXED_KEY_HALF[12] = {0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0}; /* 升号调:低半音映射 +1 */
|
||||
|
||||
/* 返回 C 调源品位 0~6;*add = 需叠加半音(调内 +1 行 + 升号调 +1,取值 0~2) */
|
||||
static uint8_t FixedKey_SourceFret(uint8_t group, uint8_t *add)
|
||||
{
|
||||
uint8_t t = (uint8_t)mGuiData[GUI_TRANSPOSE].Current % 12u;
|
||||
uint8_t row = FIXED_KEY_ROW[t];
|
||||
*add = (uint8_t)(FIXED_KEY_SHARP[row][group] + FIXED_KEY_HALF[t]);
|
||||
return (uint8_t)FIXED_KEY_SRC[row][group];
|
||||
}
|
||||
|
||||
/* 固定调填 6 弦 USE_MIDI:源品位行 + add;指板单独升号(PitchOffset==2)再 +1 */
|
||||
void FretChord_FillUseMidi(uint8_t key)
|
||||
{
|
||||
uint8_t group, type, add = 0, src;
|
||||
const STRING_MIDI *ORGAN_MIDI;
|
||||
|
||||
if (key < 1u || key > 21u)
|
||||
return;
|
||||
group = (uint8_t)((key - 1u) / 3u);
|
||||
src = FixedKey_SourceFret(group, &add);
|
||||
if (chord_type_index_map[key].PitchOffset == 2u)
|
||||
add = (uint8_t)(add + 1u);
|
||||
ORGAN_MIDI = OrganChord_Midi_Table[src];
|
||||
type = chord_type_index_map[key].type;
|
||||
USE_MIDI.Midi_1 = (uint8_t)(ORGAN_MIDI[type].Midi_1 + add);
|
||||
USE_MIDI.Midi_2 = (uint8_t)(ORGAN_MIDI[type].Midi_2 + add);
|
||||
USE_MIDI.Midi_3 = (uint8_t)(ORGAN_MIDI[type].Midi_3 + add);
|
||||
USE_MIDI.Midi_4 = (uint8_t)(ORGAN_MIDI[type].Midi_4 + add);
|
||||
USE_MIDI.Midi_5 = (uint8_t)(ORGAN_MIDI[type].Midi_5 + add);
|
||||
USE_MIDI.Midi_6 = (uint8_t)(ORGAN_MIDI[type].Midi_6 + add);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const LEBEL_UI UI_Label[] = {
|
||||
|
|
@ -854,7 +912,7 @@ void MasterVolume_Reapply(void)
|
|||
Send_volume(vol);
|
||||
}
|
||||
|
||||
/* 当前调一级大和弦:把位1 + maj + 自然音(再经 GUI_TRANSPOSE 移调 → C调即 do mi sol) */
|
||||
/* 当前调一级大和弦:把位1 + maj + 自然音(固定调映射 → C调即 do mi sol) */
|
||||
void Accomp_ApplyDefaultIChord(void)
|
||||
{
|
||||
KEY_ID_1629 = 1;
|
||||
|
|
@ -1627,9 +1685,6 @@ static void Expert_StartWithChord(uint8_t chord_id, uint8_t *midi_note_buff,
|
|||
|
||||
void TM1629_Handle(uint8_t key)
|
||||
{
|
||||
STRING_MIDI *MIDI;
|
||||
const STRING_MIDI *ORGAN_MIDI;
|
||||
|
||||
/* 指板/拍速/停止键均为用户操作 */
|
||||
ResetAutoPowerCount();
|
||||
|
||||
|
|
@ -1684,7 +1739,6 @@ void TM1629_Handle(uint8_t key)
|
|||
FreeMode_ResumePieceLoop();
|
||||
PressFlag = 1;
|
||||
}
|
||||
uint8_t group = (key - 1) / 3; /* 1~3→0, 4~6→1, ..., 19~21→6 */
|
||||
KEY_ID_1629 = key;
|
||||
/* 专业/普通(及对应设置页):记下最后指板和弦;专业同时记移调 */
|
||||
{
|
||||
|
|
@ -1698,35 +1752,8 @@ void TM1629_Handle(uint8_t key)
|
|||
else if (tab == 2 || (tab == 3 && last == 2))
|
||||
Accomp_RememberLastFretChord(key);
|
||||
}
|
||||
MIDI = (STRING_MIDI *)Chord_Midi_Table[group];
|
||||
ORGAN_MIDI = OrganChord_Midi_Table[group];
|
||||
|
||||
uint8_t type = chord_type_index_map[key].type;
|
||||
switch(chord_type_index_map[key].PitchOffset)
|
||||
{
|
||||
case 1:
|
||||
USE_MIDI.Midi_1 = ORGAN_MIDI[type].Midi_1;
|
||||
USE_MIDI.Midi_2 = ORGAN_MIDI[type].Midi_2;
|
||||
USE_MIDI.Midi_3 = ORGAN_MIDI[type].Midi_3;
|
||||
USE_MIDI.Midi_4 = ORGAN_MIDI[type].Midi_4;
|
||||
USE_MIDI.Midi_5 = ORGAN_MIDI[type].Midi_5;
|
||||
USE_MIDI.Midi_6 = ORGAN_MIDI[type].Midi_6;
|
||||
break;
|
||||
case 2:
|
||||
USE_MIDI.Midi_1 = MIDI[type].Midi_1;
|
||||
USE_MIDI.Midi_2 = MIDI[type].Midi_2;
|
||||
USE_MIDI.Midi_3 = MIDI[type].Midi_3;
|
||||
USE_MIDI.Midi_4 = MIDI[type].Midi_4;
|
||||
USE_MIDI.Midi_5 = MIDI[type].Midi_5;
|
||||
USE_MIDI.Midi_6 = MIDI[type].Midi_6;
|
||||
break;
|
||||
}
|
||||
USE_MIDI.Midi_1 += mGuiData[GUI_TRANSPOSE].Current;
|
||||
USE_MIDI.Midi_2 += mGuiData[GUI_TRANSPOSE].Current;
|
||||
USE_MIDI.Midi_3 += mGuiData[GUI_TRANSPOSE].Current;
|
||||
USE_MIDI.Midi_4 += mGuiData[GUI_TRANSPOSE].Current;
|
||||
USE_MIDI.Midi_5 += mGuiData[GUI_TRANSPOSE].Current;
|
||||
USE_MIDI.Midi_6 += mGuiData[GUI_TRANSPOSE].Current;
|
||||
/* 固定调:按当前移调取 C 调源品位六弦,不再整体加 GUI_TRANSPOSE */
|
||||
FretChord_FillUseMidi(key);
|
||||
|
||||
if(mGuiData[GUI_TAB_INDEX].Current == 1 && StartFlag)
|
||||
{
|
||||
|
|
@ -2118,11 +2145,20 @@ uint8_t GetChordNotesByType(uint8_t MIDI_Index,uint8_t type,uint8_t *buff)
|
|||
uint8_t n = 0;
|
||||
uint8_t i;
|
||||
uint8_t root;
|
||||
uint8_t add = 0;
|
||||
uint8_t src;
|
||||
|
||||
buff[0] = buff[1] = buff[2] = buff[3] = 0;
|
||||
switch(MIDI_Index)
|
||||
if (MIDI_Index < 1 || MIDI_Index > 21)
|
||||
return 0;
|
||||
|
||||
/* 固定调:按当前移调把该级映射到 C 调源品位(发音位置不变,音高随表),
|
||||
* 不再对结果整体加 GUI_TRANSPOSE。各 case 数值 = 新表 C 大调「和弦音高」列。 */
|
||||
src = FixedKey_SourceFret((uint8_t)((MIDI_Index - 1) / 3), &add);
|
||||
|
||||
switch(src)
|
||||
{
|
||||
case 1:case 2:case 3:
|
||||
case 0: /* I:C 品位 */
|
||||
switch(type)
|
||||
{
|
||||
case 0:
|
||||
|
|
@ -2154,7 +2190,7 @@ uint8_t GetChordNotesByType(uint8_t MIDI_Index,uint8_t type,uint8_t *buff)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case 4:case 5:case 6:
|
||||
case 1: /* II:D 品位 */
|
||||
switch(type)
|
||||
{
|
||||
case 0:
|
||||
|
|
@ -2186,71 +2222,71 @@ uint8_t GetChordNotesByType(uint8_t MIDI_Index,uint8_t type,uint8_t *buff)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case 7:case 8:case 9:
|
||||
case 2: /* III:E 品位(整组低八度;M/m 三和弦带 E4) */
|
||||
switch(type)
|
||||
{
|
||||
case 0:
|
||||
buff[0] = 52;buff[1] = 56;buff[2] = 59;
|
||||
buff[0] = 40;buff[1] = 44;buff[2] = 47;buff[3] = 64;
|
||||
break;
|
||||
case 1:
|
||||
buff[0] = 52;buff[1] = 55;buff[2] = 59;
|
||||
buff[0] = 40;buff[1] = 43;buff[2] = 47;buff[3] = 64;
|
||||
break;
|
||||
case 2:
|
||||
buff[0] = 52;buff[1] = 55;buff[2] = 59;buff[3] = 62;
|
||||
buff[0] = 40;buff[1] = 43;buff[2] = 47;buff[3] = 50;
|
||||
break;
|
||||
case 3:
|
||||
buff[0] = 52;buff[1] = 56;buff[2] = 59;buff[3] = 62;
|
||||
buff[0] = 40;buff[1] = 44;buff[2] = 47;buff[3] = 50;
|
||||
break;
|
||||
case 4:
|
||||
buff[0] = 52;buff[1] = 56;buff[2] = 59;buff[3] = 63;
|
||||
buff[0] = 40;buff[1] = 44;buff[2] = 47;buff[3] = 51;
|
||||
break;
|
||||
case 5:
|
||||
buff[0] = 52;buff[1] = 56;buff[2] = 59;buff[3] = 66;
|
||||
buff[0] = 40;buff[1] = 44;buff[2] = 47;buff[3] = 54;
|
||||
break;
|
||||
case 6:
|
||||
buff[0] = 52;buff[1] = 55;buff[2] = 58;buff[3] = 62;
|
||||
buff[0] = 40;buff[1] = 43;buff[2] = 46;buff[3] = 50;
|
||||
break;
|
||||
case 7:
|
||||
buff[0] = 52;buff[1] = 54;buff[2] = 59;
|
||||
buff[0] = 40;buff[1] = 42;buff[2] = 47;
|
||||
break;
|
||||
case 8:
|
||||
buff[0] = 52;buff[1] = 57;buff[2] = 59;
|
||||
buff[0] = 40;buff[1] = 45;buff[2] = 47;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 10:case 11:case 12:
|
||||
case 3: /* IV:F 品位(整组低八度) */
|
||||
switch(type)
|
||||
{
|
||||
case 0:
|
||||
buff[0] = 53;buff[1] = 57;buff[2] = 60;
|
||||
buff[0] = 41;buff[1] = 45;buff[2] = 48;
|
||||
break;
|
||||
case 1:
|
||||
buff[0] = 53;buff[1] = 56;buff[2] = 60;
|
||||
buff[0] = 41;buff[1] = 44;buff[2] = 48;
|
||||
break;
|
||||
case 2:
|
||||
buff[0] = 53;buff[1] = 56;buff[2] = 60;buff[3] = 63;
|
||||
buff[0] = 41;buff[1] = 44;buff[2] = 48;buff[3] = 51;
|
||||
break;
|
||||
case 3:
|
||||
buff[0] = 53;buff[1] = 57;buff[2] = 60;buff[3] = 63;
|
||||
buff[0] = 41;buff[1] = 45;buff[2] = 48;buff[3] = 51;
|
||||
break;
|
||||
case 4:
|
||||
buff[0] = 53;buff[1] = 57;buff[2] = 60;buff[3] = 64;
|
||||
buff[0] = 41;buff[1] = 45;buff[2] = 48;buff[3] = 52;
|
||||
break;
|
||||
case 5:
|
||||
buff[0] = 53;buff[1] = 57;buff[2] = 60;buff[3] = 67;
|
||||
buff[0] = 41;buff[1] = 45;buff[2] = 48;buff[3] = 55;
|
||||
break;
|
||||
case 6:
|
||||
buff[0] = 53;buff[1] = 56;buff[2] = 59;buff[3] = 63;
|
||||
buff[0] = 41;buff[1] = 44;buff[2] = 47;buff[3] = 51;
|
||||
break;
|
||||
case 7:
|
||||
buff[0] = 53;buff[1] = 55;buff[2] = 60;
|
||||
buff[0] = 41;buff[1] = 43;buff[2] = 48;
|
||||
break;
|
||||
case 8:
|
||||
buff[0] = 53;buff[1] = 58;buff[2] = 60;
|
||||
buff[0] = 41;buff[1] = 46;buff[2] = 48;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 13:case 14:case 15:
|
||||
case 4: /* V:G 品位 */
|
||||
switch(type)
|
||||
{
|
||||
case 0:
|
||||
|
|
@ -2282,7 +2318,7 @@ uint8_t GetChordNotesByType(uint8_t MIDI_Index,uint8_t type,uint8_t *buff)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case 16:case 17:case 18:
|
||||
case 5: /* VI:A 品位 */
|
||||
switch(type)
|
||||
{
|
||||
case 0:
|
||||
|
|
@ -2314,30 +2350,30 @@ uint8_t GetChordNotesByType(uint8_t MIDI_Index,uint8_t type,uint8_t *buff)
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case 19:case 20:case 21:
|
||||
case 6: /* VII:B 品位(Bm/B7/BM7/Bad9/Bm7-5 按新表改) */
|
||||
switch(type)
|
||||
{
|
||||
case 0:
|
||||
buff[0] = 47;buff[1] = 51;buff[2] = 53;
|
||||
break;
|
||||
case 1:
|
||||
buff[0] = 47;buff[1] = 50;buff[2] = 54;
|
||||
buff[0] = 47;buff[1] = 50;buff[2] = 53;
|
||||
break;
|
||||
case 2:
|
||||
buff[0] = 47;buff[1] = 50;buff[2] = 54;buff[3] = 57;
|
||||
break;
|
||||
case 3:
|
||||
buff[0] = 47;buff[1] = 50;buff[2] = 53;buff[3] = 57;
|
||||
break;
|
||||
case 4:
|
||||
buff[0] = 47;buff[1] = 51;buff[2] = 53;buff[3] = 57;
|
||||
break;
|
||||
case 5:
|
||||
case 4:
|
||||
buff[0] = 47;buff[1] = 51;buff[2] = 54;buff[3] = 58;
|
||||
break;
|
||||
case 6:
|
||||
case 5:
|
||||
buff[0] = 47;buff[1] = 51;buff[2] = 54;buff[3] = 60;
|
||||
break;
|
||||
case 6:
|
||||
buff[0] = 47;buff[1] = 50;buff[2] = 53;buff[3] = 57;
|
||||
break;
|
||||
case 7:
|
||||
buff[0] = 47;buff[1] = 49;buff[2] = 54;
|
||||
break;
|
||||
|
|
@ -2354,6 +2390,10 @@ uint8_t GetChordNotesByType(uint8_t MIDI_Index,uint8_t type,uint8_t *buff)
|
|||
}
|
||||
|
||||
n = (buff[3] != 0) ? 4 : 3;
|
||||
|
||||
/* 固定调:调内 +1 行 / 升号调全体 +1(替代旧的整体加 GUI_TRANSPOSE) */
|
||||
for (i = 0; i < n; i++)
|
||||
buff[i] += add;
|
||||
switch (chord_type_index_map[MIDI_Index].PitchOffset)
|
||||
{
|
||||
case 2: /* # 升:整体 +1 半音 */
|
||||
|
|
@ -2363,8 +2403,6 @@ uint8_t GetChordNotesByType(uint8_t MIDI_Index,uint8_t type,uint8_t *buff)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < n; i++)
|
||||
buff[i] += mGuiData[GUI_TRANSPOSE].Current;
|
||||
|
||||
/* 音师:仅所有调的 #四级(键 10~12 + 升)— 整组低八度,音域压在一个八度内
|
||||
* 最低音 = #IV,最高音 ≤ 自然 IV。勿对六级等其它升号和弦套用。 */
|
||||
|
|
|
|||
|
|
@ -276,6 +276,7 @@ void AppNeckLed_ClearGuide(void);
|
|||
uint8_t AppNeckLed_IsGuide(void);
|
||||
|
||||
uint8_t GetChordNotesByType(uint8_t MIDI_Index,uint8_t type,uint8_t *buff);
|
||||
void FretChord_FillUseMidi(uint8_t key);
|
||||
/* 伴奏已在播时仅更新和弦音,不 Restart(快转调) */
|
||||
void Accomp_UpdatePlayingChord(void);
|
||||
/* 切模式/停键前记住专业移调与最后指板和弦 */
|
||||
|
|
|
|||
|
|
@ -111,12 +111,20 @@ void Touch_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex,uint8_t value)
|
|||
int8_t new_trans = mGuiData[GUI_TRANSPOSE].Current;
|
||||
delta = new_trans - last_value;
|
||||
|
||||
USE_MIDI.Midi_1 += delta;
|
||||
USE_MIDI.Midi_2 += delta;
|
||||
USE_MIDI.Midi_3 += delta;
|
||||
USE_MIDI.Midi_4 += delta;
|
||||
USE_MIDI.Midi_5 += delta;
|
||||
USE_MIDI.Midi_6 += delta;
|
||||
/* 固定调:换调后按新映射重填 6 弦;未按指板时维持旧平移 */
|
||||
if (KEY_ID_1629 >= 1 && KEY_ID_1629 <= 21)
|
||||
{
|
||||
FretChord_FillUseMidi(KEY_ID_1629);
|
||||
}
|
||||
else
|
||||
{
|
||||
USE_MIDI.Midi_1 += delta;
|
||||
USE_MIDI.Midi_2 += delta;
|
||||
USE_MIDI.Midi_3 += delta;
|
||||
USE_MIDI.Midi_4 += delta;
|
||||
USE_MIDI.Midi_5 += delta;
|
||||
USE_MIDI.Midi_6 += delta;
|
||||
}
|
||||
|
||||
if(StartFlag)
|
||||
{
|
||||
|
|
@ -416,12 +424,20 @@ void UI_ApplyModeKeysOnSettings(DisplayTaskMessage_Type msg)
|
|||
USART4_SendData(transpose, 5);
|
||||
new_trans = (int8_t)mGuiData[GUI_TRANSPOSE].Current;
|
||||
delta = (int8_t)(new_trans - (int8_t)lastvalue);
|
||||
USE_MIDI.Midi_1 += delta;
|
||||
USE_MIDI.Midi_2 += delta;
|
||||
USE_MIDI.Midi_3 += delta;
|
||||
USE_MIDI.Midi_4 += delta;
|
||||
USE_MIDI.Midi_5 += delta;
|
||||
USE_MIDI.Midi_6 += delta;
|
||||
/* 固定调:换调后按新映射重填 6 弦;未按指板时维持旧平移 */
|
||||
if (KEY_ID_1629 >= 1 && KEY_ID_1629 <= 21)
|
||||
{
|
||||
FretChord_FillUseMidi(KEY_ID_1629);
|
||||
}
|
||||
else
|
||||
{
|
||||
USE_MIDI.Midi_1 += delta;
|
||||
USE_MIDI.Midi_2 += delta;
|
||||
USE_MIDI.Midi_3 += delta;
|
||||
USE_MIDI.Midi_4 += delta;
|
||||
USE_MIDI.Midi_5 += delta;
|
||||
USE_MIDI.Midi_6 += delta;
|
||||
}
|
||||
if (StartFlag && KEY_ID_1629 != 22 && KEY_ID_1629 != 23)
|
||||
Accomp_UpdatePlayingChord();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ CHORD_TYPE_INDEX chord_type_index_map[22] =
|
|||
{1, 0, 1, 0}, // index 16
|
||||
{1, 0, 1, 0}, // index 17
|
||||
{1, 0, 1, 0}, // index 18
|
||||
{0, 0, 1, 0}, // index 19
|
||||
{0, 0, 1, 0}, // index 20
|
||||
{0, 0, 1, 0}, // index 21
|
||||
{1, 0, 1, 0}, // index 19 (VII 出厂小三,对照新表 Bm)
|
||||
{1, 0, 1, 0}, // index 20
|
||||
{1, 0, 1, 0}, // index 21
|
||||
};
|
||||
|
||||
STRING_MIDI MIDI_1[] =
|
||||
|
|
@ -58,7 +58,7 @@ STRING_MIDI MIDI_2[] =
|
|||
STRING_MIDI MIDI_3[] =
|
||||
{
|
||||
{0x28,0x2F,0x34,0x38,0x3B,0x40,"E"},
|
||||
{0x28,0x37,0x3B,0x40,0x3B,0x40,"Em"},
|
||||
{0x28,0x2F,0x34,0x37,0x3B,0x40,"Em"},
|
||||
{0x28,0x2F,0x34,0x37,0x3B,0x3E,"Em7"},
|
||||
{0x28,0x2F,0x34,0x38,0x3B,0x3E,"E7"},
|
||||
{0x28,0x2F,0x34,0x38,0x3B,0x3F,"EM7"},
|
||||
|
|
@ -70,7 +70,7 @@ STRING_MIDI MIDI_3[] =
|
|||
|
||||
STRING_MIDI MIDI_4[] =
|
||||
{
|
||||
{0x29,0x39,0x3C,0x41,0x3C,0x41,"F"},
|
||||
{0x29,0x30,0x35,0x39,0x3C,0x41,"F"},
|
||||
{0x29,0x30,0x35,0x38,0x3C,0x41,"Fm"},
|
||||
{0x29,0x30,0x35,0x38,0x3C,0x3F,"Fm7"},
|
||||
{0x29,0x30,0x35,0x39,0x3C,0x3F,"F7"},
|
||||
|
|
@ -83,7 +83,7 @@ STRING_MIDI MIDI_4[] =
|
|||
|
||||
STRING_MIDI MIDI_5[] =
|
||||
{
|
||||
{0x2B,0x2F,0x37,0x3B,0x43,0x43,"G"},
|
||||
{0x2B,0x2F,0x32,0x37,0x3B,0x43,"G"},
|
||||
{0x2B,0x2E,0x32,0x37,0x3A,0x43,"Gm"},
|
||||
{0x2B,0x2E,0x32,0x37,0x3A,0x41,"Gm7"},
|
||||
{0x2B,0x2F,0x32,0x37,0x3B,0x41,"G7"},
|
||||
|
|
@ -97,7 +97,7 @@ STRING_MIDI MIDI_5[] =
|
|||
STRING_MIDI MIDI_6[] =
|
||||
{
|
||||
{0x28,0x2D,0x34,0x39,0x3D,0x40,"A"},
|
||||
{0x28,0x2D,0x39,0x3C,0x40,0x40,"Am"},
|
||||
{0x28,0x2D,0x34,0x39,0x3C,0x40,"Am"},
|
||||
{0x28,0x2D,0x34,0x37,0x3C,0x40,"Am7"},
|
||||
{0x28,0x2D,0x34,0x37,0x3D,0x40,"A7"},
|
||||
{0x28,0x2D,0x34,0x38,0x3D,0x40,"AM7"},
|
||||
|
|
@ -118,7 +118,7 @@ STRING_MIDI MIDI_7[] =
|
|||
{0x29,0x2F,0x32,0x35,0x39,0x3E,"Bm7-5"},
|
||||
{0x29,0x2F,0x31,0x36,0x3B,0x3D,"Bsus2"},
|
||||
{0x29,0x2F,0x34,0x36,0x3B,0x40,"Bsus4"},
|
||||
{0x29,0x2F,0x32,0x35,0x3B,0x3E,"Bdim"},
|
||||
{0x29,0x2F,0x32,0x35,0x3B,0x3E,"Bm-5"},
|
||||
};
|
||||
|
||||
const STRING_MIDI OrganMIDI_1[] =
|
||||
|
|
@ -150,7 +150,7 @@ const STRING_MIDI OrganMIDI_2[] =
|
|||
const STRING_MIDI OrganMIDI_3[] =
|
||||
{
|
||||
{0x28,0x2F,0x34,0x38,0x3B,0x40,"E"},
|
||||
{0x28,0x37,0x3B,0x40,0x3B,0x40,"Em"},
|
||||
{0x28,0x2F,0x34,0x37,0x3B,0x40,"Em"},
|
||||
{0x28,0x2F,0x34,0x37,0x3B,0x3E,"Em7"},
|
||||
{0x28,0x2F,0x34,0x38,0x3B,0x3E,"E7"},
|
||||
{0x28,0x2F,0x34,0x38,0x3B,0x3F,"EM7"},
|
||||
|
|
@ -162,7 +162,7 @@ const STRING_MIDI OrganMIDI_3[] =
|
|||
|
||||
const STRING_MIDI OrganMIDI_4[] =
|
||||
{
|
||||
{0x29,0x39,0x3C,0x41,0x3C,0x41,"F"},
|
||||
{0x29,0x30,0x35,0x39,0x3C,0x41,"F"},
|
||||
{0x29,0x30,0x35,0x38,0x3C,0x41,"Fm"},
|
||||
{0x29,0x30,0x35,0x38,0x3C,0x3F,"Fm7"},
|
||||
{0x29,0x30,0x35,0x39,0x3C,0x3F,"F7"},
|
||||
|
|
@ -175,7 +175,7 @@ const STRING_MIDI OrganMIDI_4[] =
|
|||
|
||||
const STRING_MIDI OrganMIDI_5[] =
|
||||
{
|
||||
{0x2B,0x2F,0x37,0x3B,0x43,0x43,"G"},
|
||||
{0x2B,0x2F,0x32,0x37,0x3B,0x43,"G"},
|
||||
{0x2B,0x2E,0x32,0x37,0x3A,0x43,"Gm"},
|
||||
{0x2B,0x2E,0x32,0x37,0x3A,0x41,"Gm7"},
|
||||
{0x2B,0x2F,0x32,0x37,0x3B,0x41,"G7"},
|
||||
|
|
@ -189,7 +189,7 @@ const STRING_MIDI OrganMIDI_5[] =
|
|||
const STRING_MIDI OrganMIDI_6[] =
|
||||
{
|
||||
{0x28,0x2D,0x34,0x39,0x3D,0x40,"A"},
|
||||
{0x28,0x2D,0x39,0x3C,0x40,0x40,"Am"},
|
||||
{0x28,0x2D,0x34,0x39,0x3C,0x40,"Am"},
|
||||
{0x28,0x2D,0x34,0x37,0x3C,0x40,"Am7"},
|
||||
{0x28,0x2D,0x34,0x37,0x3D,0x40,"A7"},
|
||||
{0x28,0x2D,0x34,0x38,0x3D,0x40,"AM7"},
|
||||
|
|
@ -210,7 +210,7 @@ const STRING_MIDI OrganMIDI_7[] =
|
|||
{0x29,0x2F,0x32,0x35,0x39,0x3E,"Bm7-5"},
|
||||
{0x29,0x2F,0x31,0x36,0x3B,0x3D,"Bsus2"},
|
||||
{0x29,0x2F,0x34,0x36,0x3B,0x40,"Bsus4"},
|
||||
{0x29,0x2F,0x32,0x35,0x3B,0x3E,"Bdim"},
|
||||
{0x29,0x2F,0x32,0x35,0x3B,0x3E,"Bm-5"},
|
||||
};
|
||||
|
||||
/* 和弦根音表索引 */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""固定调和弦六弦音高:RTT STRING_OK 对照《自动伴奏新更改和弦规则.xlsx》。
|
||||
|
||||
普通模式按下指板键后读 USE_MIDI(六弦→一弦)。先 chord xpose 再 chord key,
|
||||
因为换调命令本身不重填六弦。
|
||||
|
||||
python tools/test_fixed_key_voicing.py
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
|
||||
TOOLS = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, TOOLS)
|
||||
|
||||
from k1_harness.transports.rtt_session import open_session # noqa: E402
|
||||
|
||||
NOTE_RE = re.compile(r"STRING_OK s=(\d+) note=(\d+)")
|
||||
|
||||
# (调名, GUI_TRANSPOSE, 键, 和弦名, 六弦→一弦 MIDI)
|
||||
# 默认品质:I/IV/V 大三,II/III/VI/VII 小三。数值来自各调 sheet 对应行。
|
||||
CASES = [
|
||||
("C", 0, 1, "C", (43, 48, 52, 55, 60, 64)),
|
||||
("C", 0, 4, "Dm", (41, 45, 50, 57, 62, 65)),
|
||||
("C", 0, 7, "Em", (40, 47, 52, 55, 59, 64)),
|
||||
("C", 0, 10, "F", (41, 48, 53, 57, 60, 65)),
|
||||
("C", 0, 13, "G", (43, 47, 50, 55, 59, 67)),
|
||||
("C", 0, 16, "Am", (40, 45, 52, 57, 60, 64)),
|
||||
("C", 0, 19, "Bm", (42, 47, 50, 54, 59, 62)),
|
||||
# G:源品位 V/VI/VII/I/II/III/IV+1
|
||||
("G", 7, 1, "G", (43, 47, 50, 55, 59, 67)),
|
||||
("G", 7, 4, "Am", (40, 45, 52, 57, 60, 64)),
|
||||
("G", 7, 7, "Bm", (42, 47, 50, 54, 59, 62)),
|
||||
("G", 7, 10, "C", (43, 48, 52, 55, 60, 64)),
|
||||
("G", 7, 13, "D", (42, 45, 50, 57, 62, 66)),
|
||||
("G", 7, 16, "Em", (40, 47, 52, 55, 59, 64)),
|
||||
("G", 7, 19, "#Fm", (42, 49, 54, 58, 61, 66)),
|
||||
# D I = C 调 II 行;F# I = F 调 I 行全体 +1
|
||||
("D", 2, 1, "D", (42, 45, 50, 57, 62, 66)),
|
||||
("F#", 6, 1, "F#", (42, 49, 54, 58, 61, 66)),
|
||||
]
|
||||
|
||||
|
||||
def last_string_note(text: str, string_n: int) -> int | None:
|
||||
found = None
|
||||
for m in NOTE_RE.finditer(text or ""):
|
||||
if int(m.group(1)) == string_n:
|
||||
found = int(m.group(2))
|
||||
return found
|
||||
|
||||
|
||||
def main() -> int:
|
||||
fails = 0
|
||||
print("=== 固定调六弦音高 RTT ===", flush=True)
|
||||
with open_session(reset=False) as sess:
|
||||
sess.cmd("tone pick f", settle=1.0)
|
||||
sess.cmd("chord key 23", settle=0.3)
|
||||
sess.cmd("chord key 0", settle=0.2)
|
||||
cur_xp = None
|
||||
for key_name, xp, key, chord, notes in CASES:
|
||||
if xp != cur_xp:
|
||||
sess.cmd_ack(f"chord xpose {xp}", "CHORD_XPOSE_OK", timeout_s=2.0, retries=4)
|
||||
cur_xp = xp
|
||||
sess.cmd_ack(f"chord key {key}", "CHORD_KEY_OK", timeout_s=3.0, retries=4)
|
||||
time.sleep(0.15)
|
||||
print(f"\n-- {key_name} {chord} key={key} xp={xp}", flush=True)
|
||||
for s in range(6, 0, -1):
|
||||
expect = int(notes[6 - s])
|
||||
n0 = len(sess.lines)
|
||||
sess.cmd(f"string {s}", settle=0.12)
|
||||
sess.cmd(f"string {s} off", settle=0.05)
|
||||
got = last_string_note("\n".join(sess.lines[n0:]), s)
|
||||
ok = got == expect
|
||||
if not ok:
|
||||
fails += 1
|
||||
print(
|
||||
f" str{s} expect={expect} got={got} {'PASS' if ok else 'FAIL'}",
|
||||
flush=True,
|
||||
)
|
||||
sess.cmd_ack("chord xpose 0", "CHORD_XPOSE_OK", timeout_s=2.0, retries=2)
|
||||
sess.cmd("chord key 0", settle=0.2)
|
||||
print(f"\nFAIL={fails} / {len(CASES) * 6}", flush=True)
|
||||
return 1 if fails else 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""音色表六弦音高校对:RTT string 回报 + 麦克风基频。
|
||||
|
||||
对照 Doc/Bug/音色改善.png(C 调、移调 0)。
|
||||
I C / II Dm 保持原把位;III Em / IV F / V G / VI Am 为上移后的把位。
|
||||
对照 Doc/音色文件/自动伴奏新更改和弦规则.xlsx「C 大调」弦音高列(C 调、移调 0)。
|
||||
I C / II Dm 与旧表一致;III Em / IV F / V G / VI Am 按新表改为开放把位音高。
|
||||
只走 `string N`,不再额外 midi on 期望音,避免麦测被兜底音骗过。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
|
@ -38,10 +38,10 @@ except ImportError as exc:
|
|||
CASES = [
|
||||
("C", 1, (43, 48, 52, 55, 60, 64)),
|
||||
("Dm", 4, (41, 45, 50, 57, 62, 65)),
|
||||
("Em", 7, (40, 55, 59, 64, 59, 64)),
|
||||
("F", 10, (41, 57, 60, 65, 60, 65)),
|
||||
("G", 13, (43, 47, 55, 59, 67, 67)),
|
||||
("Am", 16, (40, 45, 57, 60, 64, 64)),
|
||||
("Em", 7, (40, 47, 52, 55, 59, 64)),
|
||||
("F", 10, (41, 48, 53, 57, 60, 65)),
|
||||
("G", 13, (43, 47, 50, 55, 59, 67)),
|
||||
("Am", 16, (40, 45, 52, 57, 60, 64)),
|
||||
]
|
||||
|
||||
SR = 48000
|
||||
|
|
|
|||
Loading…
Reference in New Issue