mirror of
https://github.com/TriM-Organization/Musicreater.git
synced 2025-02-07 19:36:46 +08:00
可以用了(?)
This commit is contained in:
parent
fc138f1dbf
commit
41883f7798
@ -41,6 +41,8 @@ DEFAULT_PROGRESSBAR_STYLE = (
|
|||||||
默认的进度条样式组
|
默认的进度条样式组
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Midi用对照表
|
||||||
|
|
||||||
MIDI_PITCH_NAME_TABLE: Dict[int, str] = {
|
MIDI_PITCH_NAME_TABLE: Dict[int, str] = {
|
||||||
0: "C",
|
0: "C",
|
||||||
1: "C#",
|
1: "C#",
|
||||||
@ -171,12 +173,468 @@ MIDI_PITCH_NAME_TABLE: Dict[int, str] = {
|
|||||||
126: "F#",
|
126: "F#",
|
||||||
127: "G",
|
127: "G",
|
||||||
}
|
}
|
||||||
|
"""Midi音高名称对照表"""
|
||||||
|
|
||||||
|
MIDI_PITCHED_NOTE_NAME_GROUP: Dict[int, Tuple[str, str]] = {
|
||||||
|
1: ("钢琴", "Piano"),
|
||||||
|
9: ("半音阶打击乐器", "Chromatic Percussion"),
|
||||||
|
17: ("风琴", "Organ"),
|
||||||
|
25: ("吉他", "Guitar"),
|
||||||
|
33: ("贝斯", "Bass"),
|
||||||
|
41: ("弦乐器", "Strings"),
|
||||||
|
49: ("合奏乐器", "Ensemble"),
|
||||||
|
57: ("铜管乐器", "Brass"),
|
||||||
|
65: ("簧乐器", "Reed"),
|
||||||
|
73: ("吹管乐器", "Pipe"),
|
||||||
|
81: ("合成主旋律", "Synth Lead"),
|
||||||
|
89: ("合成和弦", "Synth Pad"),
|
||||||
|
97: ("合成声效", "Synth Effects"),
|
||||||
|
105: ("民族乐器", "Ethnic"),
|
||||||
|
113: ("打击乐器", "Percussive"),
|
||||||
|
121: ("特殊音效", "Sound Effects"),
|
||||||
|
}
|
||||||
|
"""Midi乐音乐器分组名称对照表"""
|
||||||
|
|
||||||
|
MIDI_PITCHED_NOTE_NAME_TABLE: Dict[int, Tuple[str, str]] = {
|
||||||
|
1: ("原声平台钢琴", "Acoustic Grand Piano"),
|
||||||
|
2: ("亮音原声钢琴", "Bright Acoustic Piano"),
|
||||||
|
3: ("数码电钢琴", "Electric Grand Piano"),
|
||||||
|
4: ("酒吧钢琴", "Honky-tonk Piano"),
|
||||||
|
5: ("电气电钢琴", "Electric Piano 1(Rhodes Piano)"),
|
||||||
|
6: ("合唱效果电钢琴", "Electric Piano 2(Chorused Piano)"),
|
||||||
|
7: ("拨弦古钢琴(羽管键琴)", "Harpsichord"),
|
||||||
|
8: ("古钢琴", "Clavi"),
|
||||||
|
9: ("钢片琴", "Celesta"),
|
||||||
|
10: ("钟琴", "Glockenspiel"),
|
||||||
|
11: ("八音盒", "Music box"),
|
||||||
|
12: ("颤音琴", "Vibraphone"),
|
||||||
|
13: ("马林巴琴", "Marimba"),
|
||||||
|
14: ("木琴", "Xylophone"),
|
||||||
|
15: ("管钟", "Tubular Bells"),
|
||||||
|
16: ("扬琴", "Dulcimer"),
|
||||||
|
17: ("音栓风琴(击杆风琴)", "Drawbar Organ (Hammond Organ)"),
|
||||||
|
18: ("打击风琴", "Percussive Organ"),
|
||||||
|
19: ("摇滚管风琴", "Rock Organ"),
|
||||||
|
20: ("教堂管风琴", "Church Organ"),
|
||||||
|
21: ("簧风琴", "Reed Organ"),
|
||||||
|
22: ("手风琴", "Accordion"),
|
||||||
|
23: ("口琴", "Harmonica"),
|
||||||
|
24: ("探戈手风琴", "Tango Accordion"),
|
||||||
|
25: ("尼龙弦吉他", "Acoustic Guitar (nylon)"),
|
||||||
|
26: ("钢弦吉他", "Acoustic Guitar (steel)"),
|
||||||
|
27: ("爵士电吉他", "Electric Guitar (jazz)"),
|
||||||
|
28: ("清音电吉他", "Electric Guitar (clean)"),
|
||||||
|
29: ("弱音电吉他", "Electric Guitar (muted)"),
|
||||||
|
30: ("过驱电吉他", "Overdriven Guitar"),
|
||||||
|
31: ("失真电吉他", "Distortion Guitar"),
|
||||||
|
32: ("吉他泛音", "Guitar harmonics"),
|
||||||
|
33: ("原声贝斯", "Acoustic Bass"),
|
||||||
|
34: ("指奏电贝斯", "Electric Bass (finger)"),
|
||||||
|
35: ("拨奏电贝斯", "Electric Bass (pick)"),
|
||||||
|
36: ("无品贝斯", "Fretless Bass"),
|
||||||
|
37: ("击弦贝斯 1", "Slap Bass 1"),
|
||||||
|
38: ("击弦贝斯 2", "Slap Bass 2"),
|
||||||
|
39: ("合成贝斯 1", "Synth Bass 1"),
|
||||||
|
40: ("合成贝斯 2", "Synth Bass 2"),
|
||||||
|
41: ("小提琴", "Violin"),
|
||||||
|
42: ("中提琴", "Viola"),
|
||||||
|
43: ("大提琴", "Cello"),
|
||||||
|
44: ("低音提琴", "Contrabass"),
|
||||||
|
45: ("颤弓弦乐(弦乐震音)", "Tremolo Strings"),
|
||||||
|
46: ("弹拨弦乐(弦乐拨奏)", "Pizzicato Strings"),
|
||||||
|
47: ("竖琴", "Orchestral Harp"),
|
||||||
|
48: ("定音鼓", "Timpani"),
|
||||||
|
49: ("弦乐合奏 1", "String Ensemble 1"),
|
||||||
|
50: ("弦乐合奏 2", "String Ensemble 2"),
|
||||||
|
51: ("合成弦乐 1", "Synth Strings 1"),
|
||||||
|
52: ("合成弦乐 2", "Synth Strings 2"),
|
||||||
|
53: ("合唱“啊”音", "Choir Aahs"),
|
||||||
|
54: ("人声“嘟”音", "Voice Oohs"),
|
||||||
|
55: ("合成人声", "Synth Voice"),
|
||||||
|
56: ("交响打击乐", "Orchestra Hit"),
|
||||||
|
57: ("小号", "Trumpet"),
|
||||||
|
58: ("长号", "Trombone"),
|
||||||
|
59: ("大号", "Tuba"),
|
||||||
|
60: ("弱音小号", "Muted Trumpet"),
|
||||||
|
61: ("圆号(法国号)", "French Horn"),
|
||||||
|
62: ("铜管乐组", "Brass Section"),
|
||||||
|
63: ("合成铜管 1", "Synth Brass 1"),
|
||||||
|
64: ("合成铜管 2", "Synth Brass 2"),
|
||||||
|
65: ("高音萨克斯风", "Soprano Sax"),
|
||||||
|
66: ("中音萨克斯风", "Alto Sax"),
|
||||||
|
67: ("次中音萨克斯风", "Tenor Sax"),
|
||||||
|
68: ("上低音萨克斯风", "Baritone Sax"),
|
||||||
|
69: ("双簧管", "Oboe"),
|
||||||
|
70: ("英国管", "English Horn"),
|
||||||
|
71: ("大管(巴松管)", "Bassoon"),
|
||||||
|
72: ("单簧管(黑管)", "Clarinet"),
|
||||||
|
73: ("短笛", "Piccolo"),
|
||||||
|
74: ("长笛", "Flute"),
|
||||||
|
75: ("竖笛", "Recorder"),
|
||||||
|
76: ("排笛", "Pan Flute"),
|
||||||
|
77: ("瓶笛", "Blown Bottle"),
|
||||||
|
78: ("尺八", "Shakuhachi"),
|
||||||
|
79: ("哨子", "Whistle"),
|
||||||
|
80: ("陶笛", "Ocarina"),
|
||||||
|
81: ("方波", "Lead 1 (square)"),
|
||||||
|
82: ("锯齿波", "Lead 2 (sawtooth)"),
|
||||||
|
83: ("汽笛风琴", "Lead 3 (calliope)"),
|
||||||
|
84: ("合成吹管", "Lead 4 (chiff)"),
|
||||||
|
85: ("合成电吉他", "Lead 5 (charang)"),
|
||||||
|
86: ("人声键盘", "Lead 6 (voice)"),
|
||||||
|
87: ("五度音", "Lead 7 (fifths)"),
|
||||||
|
88: ("低音+主音", "Lead 8 (bass+lead)"),
|
||||||
|
89: ("新纪元", "Pad 1 (new age)"),
|
||||||
|
90: ("暖温", "Pad 2 (warm)"),
|
||||||
|
91: ("复合成音", "Pad 3 (polysynth)"),
|
||||||
|
92: ("人声合唱", "Pad 4 (choir)"),
|
||||||
|
93: ("弓弦", "Pad 5 (bowed)"),
|
||||||
|
94: ("银铃", "Pad 6 (metallic)"),
|
||||||
|
95: ("荣光", "Pad 7 (halo)"),
|
||||||
|
96: ("轻扫", "Pad 8 (sweep)"),
|
||||||
|
97: ("夏雨", "FX 1 (rain)"),
|
||||||
|
98: ("音轨", "FX 2 (soundtrack)"),
|
||||||
|
99: ("水晶", "FX 3 (crystal)"),
|
||||||
|
100: ("大气", "FX 4 (atmosphere)"),
|
||||||
|
101: ("轻曼", "FX 5 (light)"),
|
||||||
|
102: ("魅影", "FX 6 (goblins)"),
|
||||||
|
103: ("回响", "FX 7 (echoes)"),
|
||||||
|
104: ("科幻", "FX 8 (sci-fi)"),
|
||||||
|
105: ("西塔琴", "Sitar"),
|
||||||
|
106: ("五弦琴(班卓琴)", "Banjo"),
|
||||||
|
107: ("三味线", "Shamisen"),
|
||||||
|
108: ("日本筝", "Koto"),
|
||||||
|
109: ("卡林巴铁片琴", "Kalimba"),
|
||||||
|
110: ("苏格兰风笛", "Bagpipe"),
|
||||||
|
111: ("古提琴", "Fiddle"),
|
||||||
|
112: ("唢呐", "Shanai"),
|
||||||
|
113: ("铃铛", "Tinkle Bell"),
|
||||||
|
114: ("拉丁打铃", "Agogo"),
|
||||||
|
115: ("钢鼓", "Steel Drums"),
|
||||||
|
116: ("木块", "Woodblock"),
|
||||||
|
117: ("太鼓", "Taiko Drum"),
|
||||||
|
118: ("古式高音鼓", "Melodic Tom"),
|
||||||
|
119: ("合成鼓", "Synth Drum"),
|
||||||
|
120: ("铜钹", "Reverse Cymbal"),
|
||||||
|
121: ("吉他品格杂音", "Guitar Fret Noise"),
|
||||||
|
122: ("呼吸杂音", "Breath Noise"),
|
||||||
|
123: ("浪潮", "Seashore"),
|
||||||
|
124: ("鸟鸣", "Bird Tweet"),
|
||||||
|
125: ("电话", "Telephone"),
|
||||||
|
126: ("直升机", "Helicopter"),
|
||||||
|
127: ("鼓掌", "Applause"),
|
||||||
|
128: ("射击", "Gunshot"),
|
||||||
|
}
|
||||||
|
"""Midi乐音乐器名称对照表"""
|
||||||
|
|
||||||
|
MIDI_PERCUSSION_NOTE_NAME_TABLE: Dict[int, Tuple[str, str]] = {
|
||||||
|
35: ("原声大鼓", "Acoustic Bass Drum"),
|
||||||
|
36: ("大鼓", "Bass Drum 1"),
|
||||||
|
37: ("小鼓鼓边", "Side Stick"),
|
||||||
|
38: ("原声小军鼓", "Acoustic Snare"),
|
||||||
|
39: ("拍手", "Hand Clap"),
|
||||||
|
40: ("电子小军鼓", "Electric Snare"),
|
||||||
|
41: ("低音落地桶鼓", "Low Floor Tom"),
|
||||||
|
42: ("闭镲", "Closed Hi-Hat"),
|
||||||
|
43: ("高音落地桶鼓", "High Floor Tom"),
|
||||||
|
44: ("脚踏踩镲", "Pedal Hi-Hat"),
|
||||||
|
45: ("低桶鼓", "Low Tom"),
|
||||||
|
46: ("开镲", "Open Hi-Hat"),
|
||||||
|
47: ("低音中桶鼓", "Low-Mid Tom"),
|
||||||
|
48: ("高音中桶鼓", "Hi Mid Tom 2"),
|
||||||
|
49: ("强音钹 1", "Crash Cymbal 1"),
|
||||||
|
50: ("高桶鼓", "High Tom"),
|
||||||
|
51: ("打点钹 1", "Ride Cymbal 1"),
|
||||||
|
52: ("钹", "Chinese Cymbal"),
|
||||||
|
53: ("圆铃", "Ride Bell"),
|
||||||
|
54: ("铃鼓", "Tambourine"),
|
||||||
|
55: ("小钹铜钹", "Splash Cymbal"),
|
||||||
|
56: ("牛铃", "Cowbell"),
|
||||||
|
57: ("强音钹 2", "Crash Cymbal 2"),
|
||||||
|
58: ("颤音器", "Vibra-Slap"),
|
||||||
|
59: ("打点钹 2", "Ride Cymbal 2"),
|
||||||
|
60: ("高音邦加鼓", "Hi Bongo"),
|
||||||
|
61: ("低音邦加鼓", "Low Bongo"),
|
||||||
|
62: ("弱音高音康加鼓", "Mute Hi Conga"),
|
||||||
|
63: ("强音高音康加鼓", "Open Hi Conga"),
|
||||||
|
64: ("低音康加鼓", "Low Conga"),
|
||||||
|
65: ("高音天巴鼓", "High Timbale"),
|
||||||
|
66: ("低音天巴鼓", "Low Timbale"),
|
||||||
|
67: ("高音阿哥哥", "High Agogo"),
|
||||||
|
68: ("低音阿哥哥", "Low Agogo"),
|
||||||
|
69: ("串珠", "Cabasa"),
|
||||||
|
70: ("沙铃", "Maracas"),
|
||||||
|
71: ("短口哨", "Short Whistle"),
|
||||||
|
72: ("长口哨", "Long Whistle"),
|
||||||
|
73: ("短刮壶", "Short Guiro"),
|
||||||
|
74: ("长刮壶", "Long Guiro"),
|
||||||
|
75: ("梆子", "Claves"),
|
||||||
|
76: ("高音木块", "Hi Wood Block"),
|
||||||
|
77: ("低音木块", "Low Wood Block"),
|
||||||
|
78: ("弱音锯加鼓", "Mute Cuica"),
|
||||||
|
79: ("开音锯加鼓", "Open Cuica"),
|
||||||
|
80: ("弱音三角铁", "Mute Triangle"),
|
||||||
|
81: ("强音三角铁", "Open Triangle"),
|
||||||
|
}
|
||||||
|
"""Midi打击乐器名称对照表"""
|
||||||
|
|
||||||
|
# Minecraft用对照表
|
||||||
|
|
||||||
|
MC_PERCUSSION_INSTRUMENT_LIST: List[str] = [
|
||||||
|
"note.snare",
|
||||||
|
"note.bd",
|
||||||
|
"note.hat",
|
||||||
|
"note.basedrum",
|
||||||
|
"firework.blast",
|
||||||
|
"firework.twinkle",
|
||||||
|
"fire.ignite",
|
||||||
|
"mob.zombie.wood",
|
||||||
|
]
|
||||||
|
"""打击乐器列表"""
|
||||||
|
|
||||||
|
MC_INSTRUMENT_BLOCKS_TABLE: Dict[str, Tuple[str, ...]] = {
|
||||||
|
"note.bass": ("planks",),
|
||||||
|
"note.snare": ("sand",),
|
||||||
|
"note.hat": ("glass",),
|
||||||
|
"note.bd": ("stone",),
|
||||||
|
"note.basedrum": ("stone",),
|
||||||
|
"note.bell": ("gold_block",),
|
||||||
|
"note.flute": ("clay",),
|
||||||
|
"note.chime": ("packed_ice",),
|
||||||
|
"note.guitar": ("wool",),
|
||||||
|
"note.xylobone": ("bone_block",),
|
||||||
|
"note.iron_xylophone": ("iron_block",),
|
||||||
|
"note.cow_bell": ("soul_sand",),
|
||||||
|
"note.didgeridoo": ("pumpkin",),
|
||||||
|
"note.bit": ("emerald_block",),
|
||||||
|
"note.banjo": ("hay_block",),
|
||||||
|
"note.pling": ("glowstone",),
|
||||||
|
"note.bassattack": ("stone",), # 无法找到此音效
|
||||||
|
"note.harp": ("dirt",),
|
||||||
|
# 呃……
|
||||||
|
"firework.blast": ("sandstone",),
|
||||||
|
"firework.twinkle": ("red_sandstone",),
|
||||||
|
"fire.ignite": ("concrete_powder",),
|
||||||
|
"mob.zombie.wood": ("sand",),
|
||||||
|
}
|
||||||
|
"""MC乐器对音符盒下垫方块对照表"""
|
||||||
|
|
||||||
|
# Midi对MC通用对照表
|
||||||
|
|
||||||
|
MM_INSTRUMENT_DEVIATION_TABLE: Dict[str, int] = {
|
||||||
|
"note.harp": 6,
|
||||||
|
"note.pling": 6,
|
||||||
|
"note.guitar": 7,
|
||||||
|
"note.iron_xylophone": 6,
|
||||||
|
"note.bell": 4,
|
||||||
|
"note.xylophone": 4,
|
||||||
|
"note.chime": 4,
|
||||||
|
"note.banjo": 6,
|
||||||
|
"note.flute": 5,
|
||||||
|
"note.bass": 8,
|
||||||
|
"note.snare": -1,
|
||||||
|
"note.didgeridoo": 8,
|
||||||
|
"mob.zombie.wood": -1,
|
||||||
|
"note.bit": 6,
|
||||||
|
"note.hat": -1,
|
||||||
|
"note.bd": -1,
|
||||||
|
"firework.blast": -1,
|
||||||
|
"firework.twinkle": -1,
|
||||||
|
"fire.ignite": -1,
|
||||||
|
"note.share": -1,
|
||||||
|
"note.cow_bell": 5,
|
||||||
|
}
|
||||||
|
"""不同乐器的音调偏离对照表"""
|
||||||
|
|
||||||
|
# Midi乐器对MC乐器对照表
|
||||||
|
|
||||||
|
MM_CLASSIC_PITCHED_INSTRUMENT_TABLE: Dict[int, Tuple[str, int]] = {
|
||||||
|
0: ("note.harp", 6),
|
||||||
|
1: ("note.harp", 6),
|
||||||
|
2: ("note.pling", 6),
|
||||||
|
3: ("note.harp", 6),
|
||||||
|
4: ("note.pling", 6),
|
||||||
|
5: ("note.pling", 6),
|
||||||
|
6: ("note.harp", 6),
|
||||||
|
7: ("note.harp", 6),
|
||||||
|
8: ("note.share", -1), # 打击乐器无音域
|
||||||
|
9: ("note.harp", 6),
|
||||||
|
10: ("note.didgeridoo", 8),
|
||||||
|
11: ("note.harp", 6),
|
||||||
|
12: ("note.xylophone", 4),
|
||||||
|
13: ("note.chime", 4),
|
||||||
|
14: ("note.harp", 6),
|
||||||
|
15: ("note.harp", 6),
|
||||||
|
16: ("note.bass", 8),
|
||||||
|
17: ("note.harp", 6),
|
||||||
|
18: ("note.harp", 6),
|
||||||
|
19: ("note.harp", 6),
|
||||||
|
20: ("note.harp", 6),
|
||||||
|
21: ("note.harp", 6),
|
||||||
|
22: ("note.harp", 6),
|
||||||
|
23: ("note.guitar", 7),
|
||||||
|
24: ("note.guitar", 7),
|
||||||
|
25: ("note.guitar", 7),
|
||||||
|
26: ("note.guitar", 7),
|
||||||
|
27: ("note.guitar", 7),
|
||||||
|
28: ("note.guitar", 7),
|
||||||
|
29: ("note.guitar", 7),
|
||||||
|
30: ("note.guitar", 7),
|
||||||
|
31: ("note.bass", 8),
|
||||||
|
32: ("note.bass", 8),
|
||||||
|
33: ("note.bass", 8),
|
||||||
|
34: ("note.bass", 8),
|
||||||
|
35: ("note.bass", 8),
|
||||||
|
36: ("note.bass", 8),
|
||||||
|
37: ("note.bass", 8),
|
||||||
|
38: ("note.bass", 8),
|
||||||
|
39: ("note.bass", 8),
|
||||||
|
40: ("note.harp", 6),
|
||||||
|
41: ("note.harp", 6),
|
||||||
|
42: ("note.harp", 6),
|
||||||
|
43: ("note.harp", 6),
|
||||||
|
44: ("note.iron_xylophone", 6),
|
||||||
|
45: ("note.guitar", 7),
|
||||||
|
46: ("note.harp", 6),
|
||||||
|
47: ("note.harp", 6),
|
||||||
|
48: ("note.guitar", 7),
|
||||||
|
49: ("note.guitar", 7),
|
||||||
|
50: ("note.bit", 6),
|
||||||
|
51: ("note.bit", 6),
|
||||||
|
52: ("note.harp", 6),
|
||||||
|
53: ("note.harp", 6),
|
||||||
|
54: ("note.bit", 6),
|
||||||
|
55: ("note.flute", 5),
|
||||||
|
56: ("note.flute", 5),
|
||||||
|
57: ("note.flute", 5),
|
||||||
|
58: ("note.flute", 5),
|
||||||
|
59: ("note.flute", 5),
|
||||||
|
60: ("note.flute", 5),
|
||||||
|
61: ("note.flute", 5),
|
||||||
|
62: ("note.flute", 5),
|
||||||
|
63: ("note.flute", 5),
|
||||||
|
64: ("note.bit", 6),
|
||||||
|
65: ("note.bit", 6),
|
||||||
|
66: ("note.bit", 6),
|
||||||
|
67: ("note.bit", 6),
|
||||||
|
68: ("note.flute", 5),
|
||||||
|
69: ("note.harp", 6),
|
||||||
|
70: ("note.harp", 6),
|
||||||
|
71: ("note.flute", 5),
|
||||||
|
72: ("note.flute", 5),
|
||||||
|
73: ("note.flute", 5),
|
||||||
|
74: ("note.harp", 6),
|
||||||
|
75: ("note.flute", 5),
|
||||||
|
76: ("note.harp", 6),
|
||||||
|
77: ("note.harp", 6),
|
||||||
|
78: ("note.harp", 6),
|
||||||
|
79: ("note.harp", 6),
|
||||||
|
80: ("note.bit", 6),
|
||||||
|
81: ("note.bit", 6),
|
||||||
|
82: ("note.bit", 6),
|
||||||
|
83: ("note.bit", 6),
|
||||||
|
84: ("note.bit", 6),
|
||||||
|
85: ("note.bit", 6),
|
||||||
|
86: ("note.bit", 6),
|
||||||
|
87: ("note.bit", 6),
|
||||||
|
88: ("note.bit", 6),
|
||||||
|
89: ("note.bit", 6),
|
||||||
|
90: ("note.bit", 6),
|
||||||
|
91: ("note.bit", 6),
|
||||||
|
92: ("note.bit", 6),
|
||||||
|
93: ("note.bit", 6),
|
||||||
|
94: ("note.bit", 6),
|
||||||
|
95: ("note.bit", 6),
|
||||||
|
96: ("note.bit", 6),
|
||||||
|
97: ("note.bit", 6),
|
||||||
|
98: ("note.bit", 6),
|
||||||
|
99: ("note.bit", 6),
|
||||||
|
100: ("note.bit", 6),
|
||||||
|
101: ("note.bit", 6),
|
||||||
|
102: ("note.bit", 6),
|
||||||
|
103: ("note.bit", 6),
|
||||||
|
104: ("note.harp", 6),
|
||||||
|
105: ("note.banjo", 6),
|
||||||
|
106: ("note.harp", 6),
|
||||||
|
107: ("note.harp", 6),
|
||||||
|
108: ("note.harp", 6),
|
||||||
|
109: ("note.harp", 6),
|
||||||
|
110: ("note.harp", 6),
|
||||||
|
111: ("note.guitar", 7),
|
||||||
|
112: ("note.harp", 6),
|
||||||
|
113: ("note.bell", 4),
|
||||||
|
114: ("note.harp", 6),
|
||||||
|
115: ("note.cow_bell", 5),
|
||||||
|
116: ("note.bd", -1), # 打击乐器无音域
|
||||||
|
117: ("note.bass", 8),
|
||||||
|
118: ("note.bit", 6),
|
||||||
|
119: ("note.bd", -1), # 打击乐器无音域
|
||||||
|
120: ("note.guitar", 7),
|
||||||
|
121: ("note.harp", 6),
|
||||||
|
122: ("note.harp", 6),
|
||||||
|
123: ("note.harp", 6),
|
||||||
|
124: ("note.harp", 6),
|
||||||
|
125: ("note.hat", -1), # 打击乐器无音域
|
||||||
|
126: ("note.bd", -1), # 打击乐器无音域
|
||||||
|
127: ("note.snare", -1), # 打击乐器无音域
|
||||||
|
}
|
||||||
|
"""“经典”乐音乐器对照表"""
|
||||||
|
|
||||||
|
MM_CLASSIC_PERCUSSION_INSTRUMENT_TABLE: Dict[int, Tuple[str, int]] = {
|
||||||
|
34: ("note.bd", -1),
|
||||||
|
35: ("note.bd", -1),
|
||||||
|
36: ("note.hat", -1),
|
||||||
|
37: ("note.snare", -1),
|
||||||
|
38: ("note.snare", -1),
|
||||||
|
39: ("note.snare", -1),
|
||||||
|
40: ("note.hat", -1),
|
||||||
|
41: ("note.snare", -1),
|
||||||
|
42: ("note.hat", -1),
|
||||||
|
43: ("note.snare", -1),
|
||||||
|
44: ("note.snare", -1),
|
||||||
|
45: ("note.bell", 4),
|
||||||
|
46: ("note.snare", -1),
|
||||||
|
47: ("note.snare", -1),
|
||||||
|
48: ("note.bell", 4),
|
||||||
|
49: ("note.hat", -1),
|
||||||
|
50: ("note.bell", 4),
|
||||||
|
51: ("note.bell", 4),
|
||||||
|
52: ("note.bell", 4),
|
||||||
|
53: ("note.bell", 4),
|
||||||
|
54: ("note.bell", 4),
|
||||||
|
55: ("note.bell", 4),
|
||||||
|
56: ("note.snare", -1),
|
||||||
|
57: ("note.hat", -1),
|
||||||
|
58: ("note.chime", 4),
|
||||||
|
59: ("note.iron_xylophone", 6),
|
||||||
|
60: ("note.bd", -1),
|
||||||
|
61: ("note.bd", -1),
|
||||||
|
62: ("note.xylophone", 4),
|
||||||
|
63: ("note.xylophone", 4),
|
||||||
|
64: ("note.xylophone", 4),
|
||||||
|
65: ("note.hat", -1),
|
||||||
|
66: ("note.bell", 4),
|
||||||
|
67: ("note.bell", 4),
|
||||||
|
68: ("note.hat", -1),
|
||||||
|
69: ("note.hat", -1),
|
||||||
|
70: ("note.flute", 5),
|
||||||
|
71: ("note.flute", 5),
|
||||||
|
72: ("note.hat", -1),
|
||||||
|
73: ("note.hat", -1),
|
||||||
|
74: ("note.xylophone", 4),
|
||||||
|
75: ("note.hat", -1),
|
||||||
|
76: ("note.hat", -1),
|
||||||
|
77: ("note.xylophone", 4),
|
||||||
|
78: ("note.xylophone", 4),
|
||||||
|
79: ("note.bell", 4),
|
||||||
|
80: ("note.bell", 4),
|
||||||
|
}
|
||||||
|
"""“经典”打击乐器对照表"""
|
||||||
|
|
||||||
# 以下是由 Touch “偷吃” 带来的高准确率音效对照表
|
# 以下是由 Touch “偷吃” 带来的高准确率音效对照表
|
||||||
# 包括乐音乐器对照和打击乐器对照
|
# 包括乐音乐器对照和打击乐器对照
|
||||||
|
|
||||||
PITCHED_INSTRUMENT_TABLE: Dict[int, Tuple[str, int]] = {
|
MM_TOUCH_PITCHED_INSTRUMENT_TABLE: Dict[int, Tuple[str, int]] = {
|
||||||
0: ("note.harp", 6),
|
0: ("note.harp", 6),
|
||||||
1: ("note.harp", 6),
|
1: ("note.harp", 6),
|
||||||
2: ("note.pling", 6),
|
2: ("note.pling", 6),
|
||||||
@ -224,7 +682,7 @@ PITCHED_INSTRUMENT_TABLE: Dict[int, Tuple[str, int]] = {
|
|||||||
44: ("note.flute", 5),
|
44: ("note.flute", 5),
|
||||||
45: ("note.iron_xylophone", 6),
|
45: ("note.iron_xylophone", 6),
|
||||||
46: ("note.harp", 6),
|
46: ("note.harp", 6),
|
||||||
47: ("note.snare", 7),
|
47: ("note.snare", -1),
|
||||||
48: ("note.flute", 5),
|
48: ("note.flute", 5),
|
||||||
49: ("note.flute", 5),
|
49: ("note.flute", 5),
|
||||||
50: ("note.flute", 5),
|
50: ("note.flute", 5),
|
||||||
@ -232,7 +690,7 @@ PITCHED_INSTRUMENT_TABLE: Dict[int, Tuple[str, int]] = {
|
|||||||
52: ("note.didgeridoo", 5),
|
52: ("note.didgeridoo", 5),
|
||||||
53: ("note.flute", 5), # 合唱“啊”音
|
53: ("note.flute", 5), # 合唱“啊”音
|
||||||
54: ("note.flute", 5), # 人声“嘟”音
|
54: ("note.flute", 5), # 人声“嘟”音
|
||||||
55: ("mob.zombie.wood", 7), # 合成人声
|
55: ("mob.zombie.wood", -1), # 合成人声
|
||||||
56: ("note.flute", 5),
|
56: ("note.flute", 5),
|
||||||
57: ("note.flute", 5),
|
57: ("note.flute", 5),
|
||||||
58: ("note.flute", 5),
|
58: ("note.flute", 5),
|
||||||
@ -292,136 +750,100 @@ PITCHED_INSTRUMENT_TABLE: Dict[int, Tuple[str, int]] = {
|
|||||||
112: ("note.bell", 4),
|
112: ("note.bell", 4),
|
||||||
113: ("note.xylophone", 4),
|
113: ("note.xylophone", 4),
|
||||||
114: ("note.flute", 5),
|
114: ("note.flute", 5),
|
||||||
115: ("note.hat", 7), # 打击乐器无音域
|
115: ("note.hat", -1), # 打击乐器无音域
|
||||||
116: ("note.snare", 7), # 打击乐器无音域
|
116: ("note.snare", -1), # 打击乐器无音域
|
||||||
117: ("note.snare", 7), # 打击乐器无音域
|
117: ("note.snare", -1), # 打击乐器无音域
|
||||||
118: ("note.bd", 7), # 打击乐器无音域
|
118: ("note.bd", -1), # 打击乐器无音域
|
||||||
119: ("firework.blast", 7), # 打击乐器无音域
|
119: ("firework.blast", -1), # 打击乐器无音域
|
||||||
120: ("note.guitar", 7), # 吉他还把杂音
|
120: ("note.guitar", 7), # 吉他还把杂音
|
||||||
121: ("note.harp", 6), # 呼吸声
|
121: ("note.harp", 6), # 呼吸声
|
||||||
122: ("note.harp", 6), # 海浪声
|
122: ("note.harp", 6), # 海浪声
|
||||||
123: ("note.harp", 6), # 鸟鸣
|
123: ("note.harp", 6), # 鸟鸣
|
||||||
124: ("note.bit", 6),
|
124: ("note.bit", 6),
|
||||||
125: ("note.hat", 7), # 直升机
|
125: ("note.hat", -1), # 直升机
|
||||||
126: ("firework.twinkle", 7), # 打击乐器无音域
|
126: ("firework.twinkle", -1), # 打击乐器无音域
|
||||||
127: ("mob.zombie.wood", 7), # 打击乐器无音域
|
127: ("mob.zombie.wood", -1), # 打击乐器无音域
|
||||||
}
|
}
|
||||||
|
"""“偷吃”乐音乐器对照表"""
|
||||||
|
|
||||||
PERCUSSION_INSTRUMENT_TABLE: Dict[int, Tuple[str, int]] = {
|
MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE: Dict[int, Tuple[str, int]] = {
|
||||||
34: ("note.hat", 7),
|
34: ("note.hat", -1),
|
||||||
35: ("note.bd", 7),
|
35: ("note.bd", -1),
|
||||||
36: ("note.bd", 7),
|
36: ("note.bd", -1),
|
||||||
37: ("note.snare", 7),
|
37: ("note.snare", -1),
|
||||||
38: ("note.snare", 7),
|
38: ("note.snare", -1),
|
||||||
39: ("fire.ignite", 7),
|
39: ("fire.ignite", 7),
|
||||||
40: ("note.snare", 7),
|
40: ("note.snare", -1),
|
||||||
41: ("note.hat", 7),
|
41: ("note.hat", -1),
|
||||||
42: ("note.hat", 7),
|
42: ("note.hat", -1),
|
||||||
43: ("firework.blast", 7),
|
43: ("firework.blast", -1),
|
||||||
44: ("note.hat", 7),
|
44: ("note.hat", -1),
|
||||||
45: ("note.snare", 4),
|
45: ("note.snare", -1),
|
||||||
46: ("note.snare", 7),
|
46: ("note.snare", -1),
|
||||||
47: ("note.snare", 7),
|
47: ("note.snare", -1),
|
||||||
48: ("note.bell", 4),
|
48: ("note.bell", 4),
|
||||||
49: ("note.hat", 7),
|
49: ("note.hat", -1),
|
||||||
50: ("note.bell", 4),
|
50: ("note.bell", 4),
|
||||||
51: ("note.bell", 4),
|
51: ("note.bell", 4),
|
||||||
52: ("note.bell", 4),
|
52: ("note.bell", 4),
|
||||||
53: ("note.bell", 4),
|
53: ("note.bell", 4),
|
||||||
54: ("note.bell", 4),
|
54: ("note.bell", 4),
|
||||||
55: ("note.bell", 4),
|
55: ("note.bell", 4),
|
||||||
56: ("note.snare", 7),
|
56: ("note.snare", -1),
|
||||||
57: ("note.hat", 7),
|
57: ("note.hat", -1),
|
||||||
58: ("note.chime", 4),
|
58: ("note.chime", 4),
|
||||||
59: ("note.iron_xylophone", 6),
|
59: ("note.iron_xylophone", 6),
|
||||||
60: ("note.bd", 7),
|
60: ("note.bd", -1),
|
||||||
61: ("note.bd", 7),
|
61: ("note.bd", -1),
|
||||||
62: ("note.xylophone", 4),
|
62: ("note.xylophone", 4),
|
||||||
63: ("note.xylophone", 4),
|
63: ("note.xylophone", 4),
|
||||||
64: ("note.xylophone", 4),
|
64: ("note.xylophone", 4),
|
||||||
65: ("note.hat", 7),
|
65: ("note.hat", -1),
|
||||||
66: ("note.bell", 4),
|
66: ("note.bell", 4),
|
||||||
67: ("note.bell", 4),
|
67: ("note.bell", 4),
|
||||||
68: ("note.hat", 7),
|
68: ("note.hat", -1),
|
||||||
69: ("note.hat", 7),
|
69: ("note.hat", -1),
|
||||||
70: ("note.flute", 5),
|
70: ("note.flute", 5),
|
||||||
71: ("note.flute", 5),
|
71: ("note.flute", 5),
|
||||||
72: ("note.hat", 7),
|
72: ("note.hat", -1),
|
||||||
73: ("note.hat", 7),
|
73: ("note.hat", -1),
|
||||||
74: ("note.xylophone", 4),
|
74: ("note.xylophone", 4),
|
||||||
75: ("note.hat", 7),
|
75: ("note.hat", -1),
|
||||||
76: ("note.hat", 7),
|
76: ("note.hat", -1),
|
||||||
77: ("note.xylophone", 4),
|
77: ("note.xylophone", 4),
|
||||||
78: ("note.xylophone", 4),
|
78: ("note.xylophone", 4),
|
||||||
79: ("note.bell", 4),
|
79: ("note.bell", 4),
|
||||||
80: ("note.bell", 4),
|
80: ("note.bell", 4),
|
||||||
}
|
}
|
||||||
|
"""“偷吃”打击乐器对照表"""
|
||||||
PERCUSSION_INSTRUMENT_LIST: List[str] = [
|
|
||||||
"note.snare",
|
|
||||||
"note.bd",
|
|
||||||
"note.hat",
|
|
||||||
"note.basedrum",
|
|
||||||
"firework.blast",
|
|
||||||
"firework.twinkle",
|
|
||||||
"fire.ignite",
|
|
||||||
"mob.zombie.wood",
|
|
||||||
]
|
|
||||||
|
|
||||||
INSTRUMENT_BLOCKS_TABLE: Dict[str, Tuple[str, ...]] = {
|
|
||||||
"note.bass": ("planks",),
|
|
||||||
"note.snare": ("sand",),
|
|
||||||
"note.hat": ("glass",),
|
|
||||||
"note.bd": ("stone",),
|
|
||||||
"note.basedrum": ("stone",),
|
|
||||||
"note.bell": ("gold_block",),
|
|
||||||
"note.flute": ("clay",),
|
|
||||||
"note.chime": ("packed_ice",),
|
|
||||||
"note.guitar": ("wool",),
|
|
||||||
"note.xylobone": ("bone_block",),
|
|
||||||
"note.iron_xylophone": ("iron_block",),
|
|
||||||
"note.cow_bell": ("soul_sand",),
|
|
||||||
"note.didgeridoo": ("pumpkin",),
|
|
||||||
"note.bit": ("emerald_block",),
|
|
||||||
"note.banjo": ("hay_block",),
|
|
||||||
"note.pling": ("glowstone",),
|
|
||||||
"note.bassattack": ("command_block",), # 无法找到此音效
|
|
||||||
"note.harp": ("dirt",),
|
|
||||||
# 呃……
|
|
||||||
"firework.blast": ("sandstone",),
|
|
||||||
"firework.twinkle": ("red_sandstone",),
|
|
||||||
"fire.ignite": ("concrete_powder",),
|
|
||||||
"mob.zombie.wood": ("sand",),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# 即将启用
|
# 即将启用
|
||||||
height2note = {
|
# height2note = {
|
||||||
0.5: 0,
|
# 0.5: 0,
|
||||||
0.53: 1,
|
# 0.53: 1,
|
||||||
0.56: 2,
|
# 0.56: 2,
|
||||||
0.6: 3,
|
# 0.6: 3,
|
||||||
0.63: 4,
|
# 0.63: 4,
|
||||||
0.67: 5,
|
# 0.67: 5,
|
||||||
0.7: 6,
|
# 0.7: 6,
|
||||||
0.75: 7,
|
# 0.75: 7,
|
||||||
0.8: 8,
|
# 0.8: 8,
|
||||||
0.84: 9,
|
# 0.84: 9,
|
||||||
0.9: 10,
|
# 0.9: 10,
|
||||||
0.94: 11,
|
# 0.94: 11,
|
||||||
1.0: 12,
|
# 1.0: 12,
|
||||||
1.05: 13,
|
# 1.05: 13,
|
||||||
1.12: 14,
|
# 1.12: 14,
|
||||||
1.2: 15,
|
# 1.2: 15,
|
||||||
1.25: 16,
|
# 1.25: 16,
|
||||||
1.33: 17,
|
# 1.33: 17,
|
||||||
1.4: 18,
|
# 1.4: 18,
|
||||||
1.5: 19,
|
# 1.5: 19,
|
||||||
1.6: 20,
|
# 1.6: 20,
|
||||||
1.7: 21,
|
# 1.7: 21,
|
||||||
1.8: 22,
|
# 1.8: 22,
|
||||||
1.9: 23,
|
# 1.9: 23,
|
||||||
2.0: 24,
|
# 2.0: 24,
|
||||||
}
|
# }
|
||||||
"""音高对照表\n
|
# """音高对照表\n
|
||||||
MC音高:音符盒音调"""
|
# MC音高:音符盒音调"""
|
||||||
|
@ -16,14 +16,12 @@ Terms & Conditions: License.md in the root directory
|
|||||||
# Email TriM-Organization@hotmail.com
|
# Email TriM-Organization@hotmail.com
|
||||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||||
|
|
||||||
import random
|
|
||||||
|
|
||||||
from .constants import INSTRUMENT_BLOCKS_TABLE
|
|
||||||
from .exceptions import *
|
from .exceptions import *
|
||||||
from .main import MidiConvert
|
|
||||||
from .subclass import *
|
from .subclass import *
|
||||||
from .utils import *
|
from .utils import *
|
||||||
from .types import Tuple, List, Dict
|
from .main import MidiConvert, MM_CLASSIC_PERCUSSION_INSTRUMENT_TABLE, MM_CLASSIC_PITCHED_INSTRUMENT_TABLE
|
||||||
|
from .types import Tuple, List, Dict, ChannelType
|
||||||
|
|
||||||
|
|
||||||
class FutureMidiConvertRSNB(MidiConvert):
|
class FutureMidiConvertRSNB(MidiConvert):
|
||||||
@ -34,30 +32,6 @@ class FutureMidiConvertRSNB(MidiConvert):
|
|||||||
music_command_list: Dict[int, SingleNoteBox]
|
music_command_list: Dict[int, SingleNoteBox]
|
||||||
"""音乐指令列表"""
|
"""音乐指令列表"""
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def soundID_to_block(sound_id: str, random_select: bool = False) -> str:
|
|
||||||
"""
|
|
||||||
将我的世界乐器名改作音符盒所需的对应方块名称
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
sound_id: str
|
|
||||||
将我的世界乐器名
|
|
||||||
random_select: bool
|
|
||||||
是否随机选取对应方块
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
str方块名称
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
if random_select:
|
|
||||||
return random.choice(INSTRUMENT_BLOCKS_TABLE[sound_id])
|
|
||||||
else:
|
|
||||||
return INSTRUMENT_BLOCKS_TABLE[sound_id][0]
|
|
||||||
except KeyError:
|
|
||||||
return "air"
|
|
||||||
|
|
||||||
|
|
||||||
class FutureMidiConvertM4(MidiConvert):
|
class FutureMidiConvertM4(MidiConvert):
|
||||||
"""
|
"""
|
||||||
@ -101,6 +75,7 @@ class FutureMidiConvertM4(MidiConvert):
|
|||||||
lastime=int(_note.duration / totalCount),
|
lastime=int(_note.duration / totalCount),
|
||||||
track_number=_note.track_no,
|
track_number=_note.track_no,
|
||||||
is_percussion=_note.percussive,
|
is_percussion=_note.percussive,
|
||||||
|
extra_information=_note.extra_info
|
||||||
)
|
)
|
||||||
# (
|
# (
|
||||||
# _note.start_time + _i * _apply_time_division,
|
# _note.start_time + _i * _apply_time_division,
|
||||||
@ -145,8 +120,11 @@ class FutureMidiConvertM4(MidiConvert):
|
|||||||
# 此处 我们把通道视为音轨
|
# 此处 我们把通道视为音轨
|
||||||
for channel in self.to_music_note_channels().values():
|
for channel in self.to_music_note_channels().values():
|
||||||
for note in channel:
|
for note in channel:
|
||||||
|
note.set_info(note_to_command_parameters(note,self.percussion_note_referrence_table if note.percussive else self.pitched_note_reference_table, (max_volume) if note.track_no == 0 else (max_volume * 0.9),self.volume_processing_function,))
|
||||||
|
|
||||||
|
|
||||||
if not note.percussive:
|
if not note.percussive:
|
||||||
notes_list.extend(self._linear_note(note, note.get_mc_pitch * 500))
|
notes_list.extend(self._linear_note(note, note.extra_info[3] * 500))
|
||||||
else:
|
else:
|
||||||
notes_list.append(note)
|
notes_list.append(note)
|
||||||
|
|
||||||
@ -166,12 +144,12 @@ class FutureMidiConvertM4(MidiConvert):
|
|||||||
self.music_command_list.append(
|
self.music_command_list.append(
|
||||||
SingleCommand(
|
SingleCommand(
|
||||||
self.execute_cmd_head.format(player_selector)
|
self.execute_cmd_head.format(player_selector)
|
||||||
+ note.to_command(max_volume),
|
+ r"playsound {} @s ^ ^ ^{} {} {}".format(*note.extra_info),
|
||||||
tick_delay=tickdelay,
|
tick_delay=tickdelay,
|
||||||
annotation="在{}播放{}%的{}音".format(
|
annotation="在{}播放{}%的{}音".format(
|
||||||
mctick2timestr(delaytime_now),
|
mctick2timestr(delaytime_now),
|
||||||
max_volume * 100,
|
max_volume * 100,
|
||||||
"{}:{}".format(note.mc_sound_ID, note.mc_pitch),
|
"{}:{}".format(note.extra_info[0], note.extra_info[3]),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -186,6 +164,82 @@ class FutureMidiConvertM5(MidiConvert):
|
|||||||
加入同刻偏移算法优化音感
|
加入同刻偏移算法优化音感
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def to_music_channels(
|
||||||
|
self,
|
||||||
|
) -> ChannelType:
|
||||||
|
"""
|
||||||
|
使用金羿的转换思路,将midi解析并转换为频道信息字典
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
以频道作为分割的Midi信息字典:
|
||||||
|
Dict[int,Dict[int,List[Union[Tuple[Literal["PgmC"], int, int],Tuple[Literal["NoteS"], int, int, int],Tuple[Literal["NoteE"], int, int],]],],]
|
||||||
|
"""
|
||||||
|
if self.midi is None:
|
||||||
|
raise MidiUnboundError(
|
||||||
|
"你是否正在使用的是一个由 copy_important 生成的MidiConvert对象?这是不可复用的。"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 一个midi中仅有16个通道 我们通过通道来识别而不是音轨
|
||||||
|
midi_channels: ChannelType = empty_midi_channels()
|
||||||
|
tempo = 500000
|
||||||
|
|
||||||
|
# 我们来用通道统计音乐信息
|
||||||
|
# 但是是用分轨的思路的
|
||||||
|
for track_no, track in enumerate(self.midi.tracks):
|
||||||
|
microseconds = 0
|
||||||
|
if not track:
|
||||||
|
continue
|
||||||
|
|
||||||
|
note_queue = empty_midi_channels(staff=[])
|
||||||
|
|
||||||
|
for msg in track:
|
||||||
|
if msg.time != 0:
|
||||||
|
microseconds += msg.time * tempo / self.midi.ticks_per_beat / 1000
|
||||||
|
|
||||||
|
if msg.is_meta:
|
||||||
|
if msg.type == "set_tempo":
|
||||||
|
tempo = msg.tempo
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
if not track_no in midi_channels[msg.channel].keys():
|
||||||
|
midi_channels[msg.channel][track_no] = []
|
||||||
|
except AttributeError as E:
|
||||||
|
print(msg, E)
|
||||||
|
|
||||||
|
if msg.type == "program_change":
|
||||||
|
midi_channels[msg.channel][track_no].append(
|
||||||
|
("PgmC", msg.program, microseconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
elif msg.type == "note_on" and msg.velocity != 0:
|
||||||
|
midi_channels[msg.channel][track_no].append(
|
||||||
|
("NoteS", msg.note, msg.velocity, microseconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
elif (msg.type == "note_on" and msg.velocity == 0) or (
|
||||||
|
msg.type == "note_off"
|
||||||
|
):
|
||||||
|
midi_channels[msg.channel][track_no].append(
|
||||||
|
("NoteE", msg.note, microseconds)
|
||||||
|
)
|
||||||
|
|
||||||
|
"""整合后的音乐通道格式
|
||||||
|
每个通道包括若干消息元素其中逃不过这三种:
|
||||||
|
|
||||||
|
1 切换乐器消息
|
||||||
|
("PgmC", 切换后的乐器ID: int, 距离演奏开始的毫秒)
|
||||||
|
|
||||||
|
2 音符开始消息
|
||||||
|
("NoteS", 开始的音符ID, 力度(响度), 距离演奏开始的毫秒)
|
||||||
|
|
||||||
|
3 音符结束消息
|
||||||
|
("NoteE", 结束的音符ID, 距离演奏开始的毫秒)"""
|
||||||
|
del tempo, self.channels
|
||||||
|
self.channels: ChannelType = midi_channels
|
||||||
|
# [print([print(no,tno,sum([True if i[0] == 'NoteS' else False for i in track])) for tno,track in cna.items()]) if cna else False for no,cna in midi_channels.items()]
|
||||||
|
return midi_channels
|
||||||
|
|
||||||
# 神奇的偏移音
|
# 神奇的偏移音
|
||||||
def to_command_list_in_delay(
|
def to_command_list_in_delay(
|
||||||
self,
|
self,
|
||||||
@ -237,9 +291,9 @@ class FutureMidiConvertM5(MidiConvert):
|
|||||||
|
|
||||||
elif msg[0] == "NoteS":
|
elif msg[0] == "NoteS":
|
||||||
soundID, _X = (
|
soundID, _X = (
|
||||||
self.perc_inst_to_soundID_withX(msg[1])
|
inst_to_sould_with_deviation(msg[1],MM_CLASSIC_PERCUSSION_INSTRUMENT_TABLE)
|
||||||
if SpecialBits
|
if SpecialBits
|
||||||
else self.inst_to_souldID_withX(InstID)
|
else inst_to_sould_with_deviation(InstID,MM_CLASSIC_PITCHED_INSTRUMENT_TABLE)
|
||||||
)
|
)
|
||||||
|
|
||||||
score_now = round(msg[-1] / float(speed) / 50)
|
score_now = round(msg[-1] / float(speed) / 50)
|
||||||
|
@ -77,6 +77,15 @@ class MidiConvert:
|
|||||||
midi: VoidMido
|
midi: VoidMido
|
||||||
"""MidiFile对象"""
|
"""MidiFile对象"""
|
||||||
|
|
||||||
|
pitched_note_reference_table: Dict[int, Tuple[str, int]]
|
||||||
|
"""乐音乐器Midi-MC对照表"""
|
||||||
|
|
||||||
|
percussion_note_referrence_table: Dict[int, Tuple[str, int]]
|
||||||
|
"""打击乐器Midi-MC对照表"""
|
||||||
|
|
||||||
|
volume_processing_function: Callable[[float], float]
|
||||||
|
"""音量处理函数"""
|
||||||
|
|
||||||
midi_music_name: str
|
midi_music_name: str
|
||||||
"""Midi乐曲名"""
|
"""Midi乐曲名"""
|
||||||
|
|
||||||
@ -103,6 +112,13 @@ class MidiConvert:
|
|||||||
midi_obj: VoidMido,
|
midi_obj: VoidMido,
|
||||||
midi_name: str,
|
midi_name: str,
|
||||||
enable_old_exe_format: bool = False,
|
enable_old_exe_format: bool = False,
|
||||||
|
pitched_note_rtable: Dict[
|
||||||
|
int, Tuple[str, int]
|
||||||
|
] = MM_TOUCH_PITCHED_INSTRUMENT_TABLE,
|
||||||
|
percussion_note_rtable: Dict[
|
||||||
|
int, Tuple[str, int]
|
||||||
|
] = MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE,
|
||||||
|
vol_processing_function: Callable[[float], float] = natural_curve,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
简单的midi转换类,将midi对象转换为我的世界结构或者包
|
简单的midi转换类,将midi对象转换为我的世界结构或者包
|
||||||
@ -115,6 +131,10 @@ class MidiConvert:
|
|||||||
此音乐之名
|
此音乐之名
|
||||||
enable_old_exe_format: bool
|
enable_old_exe_format: bool
|
||||||
是否启用旧版(≤1.19)指令格式,默认为否
|
是否启用旧版(≤1.19)指令格式,默认为否
|
||||||
|
pitched_note_rtable: Dict[int, Tuple[str, int]]
|
||||||
|
乐音乐器Midi-MC对照表
|
||||||
|
percussion_note_rtable: Dict[int, Tuple[str, int]]
|
||||||
|
打击乐器Midi-MC对照表
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.midi: VoidMido = midi_obj
|
self.midi: VoidMido = midi_obj
|
||||||
@ -129,6 +149,10 @@ class MidiConvert:
|
|||||||
else "execute as {} at @s positioned ~ ~ ~ run "
|
else "execute as {} at @s positioned ~ ~ ~ run "
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.pitched_note_reference_table = pitched_note_rtable
|
||||||
|
self.percussion_note_referrence_table = percussion_note_rtable
|
||||||
|
self.volume_processing_function = vol_processing_function
|
||||||
|
|
||||||
self.progress_bar_command = self.music_command_list = []
|
self.progress_bar_command = self.music_command_list = []
|
||||||
self.channels = {}
|
self.channels = {}
|
||||||
self.music_tick_num = 0
|
self.music_tick_num = 0
|
||||||
@ -138,6 +162,13 @@ class MidiConvert:
|
|||||||
cls,
|
cls,
|
||||||
midi_file_path: str,
|
midi_file_path: str,
|
||||||
old_exe_format: bool = False,
|
old_exe_format: bool = False,
|
||||||
|
pitched_note_table: Dict[
|
||||||
|
int, Tuple[str, int]
|
||||||
|
] = MM_TOUCH_PITCHED_INSTRUMENT_TABLE,
|
||||||
|
percussion_note_table: Dict[
|
||||||
|
int, Tuple[str, int]
|
||||||
|
] = MM_TOUCH_PERCUSSION_INSTRUMENT_TABLE,
|
||||||
|
vol_processing_func: Callable[[float], float] = natural_curve,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
直接输入文件地址,将midi文件读入
|
直接输入文件地址,将midi文件读入
|
||||||
@ -148,6 +179,10 @@ class MidiConvert:
|
|||||||
midi文件地址
|
midi文件地址
|
||||||
enable_old_exe_format: bool
|
enable_old_exe_format: bool
|
||||||
是否启用旧版(≤1.19)指令格式,默认为否
|
是否启用旧版(≤1.19)指令格式,默认为否
|
||||||
|
pitched_note_table: Dict[int, Tuple[str, int]]
|
||||||
|
乐音乐器Midi-MC对照表
|
||||||
|
percussion_note_table: Dict[int, Tuple[str, int]]
|
||||||
|
打击乐器Midi-MC对照表
|
||||||
"""
|
"""
|
||||||
|
|
||||||
midi_music_name = os.path.splitext(os.path.basename(midi_file_path))[0].replace(
|
midi_music_name = os.path.splitext(os.path.basename(midi_file_path))[0].replace(
|
||||||
@ -160,6 +195,9 @@ class MidiConvert:
|
|||||||
mido.MidiFile(midi_file_path, clip=True),
|
mido.MidiFile(midi_file_path, clip=True),
|
||||||
midi_music_name,
|
midi_music_name,
|
||||||
old_exe_format,
|
old_exe_format,
|
||||||
|
pitched_note_table,
|
||||||
|
percussion_note_table,
|
||||||
|
vol_processing_func,
|
||||||
)
|
)
|
||||||
except (ValueError, TypeError) as E:
|
except (ValueError, TypeError) as E:
|
||||||
raise MidiDestroyedError(f"文件{midi_file_path}损坏:{E}")
|
raise MidiDestroyedError(f"文件{midi_file_path}损坏:{E}")
|
||||||
@ -447,6 +485,7 @@ class MidiConvert:
|
|||||||
|
|
||||||
def to_music_note_channels(
|
def to_music_note_channels(
|
||||||
self,
|
self,
|
||||||
|
default_tempo_value: int = mido.midifiles.midifiles.DEFAULT_TEMPO,
|
||||||
ignore_mismatch_error: bool = True,
|
ignore_mismatch_error: bool = True,
|
||||||
) -> NoteChannelType:
|
) -> NoteChannelType:
|
||||||
"""
|
"""
|
||||||
@ -465,7 +504,7 @@ class MidiConvert:
|
|||||||
|
|
||||||
# 一个midi中仅有16个通道 我们通过通道来识别而不是音轨
|
# 一个midi中仅有16个通道 我们通过通道来识别而不是音轨
|
||||||
midi_channels: NoteChannelType = empty_midi_channels(staff=[])
|
midi_channels: NoteChannelType = empty_midi_channels(staff=[])
|
||||||
tempo = mido.midifiles.midifiles.DEFAULT_TEMPO
|
tempo = default_tempo_value
|
||||||
|
|
||||||
# 我们来用通道统计音乐信息
|
# 我们来用通道统计音乐信息
|
||||||
# 但是是用分轨的思路的
|
# 但是是用分轨的思路的
|
||||||
@ -624,6 +663,20 @@ class MidiConvert:
|
|||||||
score_now = round(note.start_time / float(speed) / 50)
|
score_now = round(note.start_time / float(speed) / 50)
|
||||||
max_score = max(max_score, score_now)
|
max_score = max(max_score, score_now)
|
||||||
|
|
||||||
|
(
|
||||||
|
mc_sound_ID,
|
||||||
|
mc_distance_volume,
|
||||||
|
volume_percentage,
|
||||||
|
mc_pitch,
|
||||||
|
) = note_to_command_parameters(
|
||||||
|
note,
|
||||||
|
self.percussion_note_referrence_table
|
||||||
|
if note.percussive
|
||||||
|
else self.pitched_note_reference_table,
|
||||||
|
(max_volume) if note.track_no == 0 else (max_volume * 0.9),
|
||||||
|
self.volume_processing_function,
|
||||||
|
)
|
||||||
|
|
||||||
this_channel.append(
|
this_channel.append(
|
||||||
SingleCommand(
|
SingleCommand(
|
||||||
self.execute_cmd_head.format(
|
self.execute_cmd_head.format(
|
||||||
@ -631,13 +684,13 @@ class MidiConvert:
|
|||||||
.replace("(", r"{")
|
.replace("(", r"{")
|
||||||
.replace(")", r"}")
|
.replace(")", r"}")
|
||||||
)
|
)
|
||||||
+ note.to_command(
|
+ r"playsound {} @s ^ ^ ^{} {} {}".format(
|
||||||
(max_volume) if note.track_no == 0 else (max_volume * 0.9)
|
mc_sound_ID, mc_distance_volume, volume_percentage, mc_pitch
|
||||||
),
|
),
|
||||||
annotation="在{}播放{}%的{}音".format(
|
annotation="在{}播放{}%的{}音".format(
|
||||||
mctick2timestr(score_now),
|
mctick2timestr(score_now),
|
||||||
max_volume * 100,
|
max_volume * 100,
|
||||||
"{}:{}".format(note.mc_sound_ID, note.mc_pitch),
|
"{}:{:.2f}".format(mc_sound_ID, mc_pitch),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -697,17 +750,35 @@ class MidiConvert:
|
|||||||
else:
|
else:
|
||||||
max_multi = max(max_multi, multi)
|
max_multi = max(max_multi, multi)
|
||||||
multi = 0
|
multi = 0
|
||||||
|
|
||||||
|
(
|
||||||
|
mc_sound_ID,
|
||||||
|
mc_distance_volume,
|
||||||
|
volume_percentage,
|
||||||
|
mc_pitch,
|
||||||
|
) = note_to_command_parameters(
|
||||||
|
note,
|
||||||
|
self.percussion_note_referrence_table
|
||||||
|
if note.percussive
|
||||||
|
else self.pitched_note_reference_table,
|
||||||
|
(max_volume) if note.track_no == 0 else (max_volume * 0.9),
|
||||||
|
self.volume_processing_function,
|
||||||
|
)
|
||||||
|
|
||||||
self.music_command_list.append(
|
self.music_command_list.append(
|
||||||
SingleCommand(
|
SingleCommand(
|
||||||
self.execute_cmd_head.format(player_selector)
|
self.execute_cmd_head.format(player_selector)
|
||||||
+ note.to_command(
|
+ r"playsound {} @s ^ ^ ^{} {} {}".format(
|
||||||
(max_volume) if note.track_no == 0 else (max_volume * 0.9)
|
mc_sound_ID,
|
||||||
|
mc_distance_volume,
|
||||||
|
volume_percentage,
|
||||||
|
mc_pitch,
|
||||||
),
|
),
|
||||||
tick_delay=tickdelay,
|
tick_delay=tickdelay,
|
||||||
annotation="在{}播放{}%的{}音".format(
|
annotation="在{}播放{}%的{}音".format(
|
||||||
mctick2timestr(delaytime_now),
|
mctick2timestr(delaytime_now),
|
||||||
max_volume * 100,
|
max_volume * 100,
|
||||||
"{}:{}".format(note.mc_sound_ID, note.mc_pitch),
|
"{}:{:.2f}".format(mc_sound_ID, mc_pitch),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -19,7 +19,7 @@ Terms & Conditions: License.md in the root directory
|
|||||||
from ..exceptions import NotDefineProgramError, ZeroSpeedError
|
from ..exceptions import NotDefineProgramError, ZeroSpeedError
|
||||||
from ..main import MidiConvert
|
from ..main import MidiConvert
|
||||||
from ..subclass import SingleCommand
|
from ..subclass import SingleCommand
|
||||||
from ..utils import inst_to_souldID_withX, perc_inst_to_soundID_withX
|
from ..utils import inst_to_sould_with_deviation, perc_inst_to_soundID_withX
|
||||||
|
|
||||||
# 你以为写完了吗?其实并没有
|
# 你以为写完了吗?其实并没有
|
||||||
|
|
||||||
@ -71,13 +71,13 @@ def to_note_list(
|
|||||||
soundID, _X = (
|
soundID, _X = (
|
||||||
perc_inst_to_soundID_withX(InstID)
|
perc_inst_to_soundID_withX(InstID)
|
||||||
if SpecialBits
|
if SpecialBits
|
||||||
else inst_to_souldID_withX(InstID)
|
else inst_to_sould_with_deviation(InstID)
|
||||||
)
|
)
|
||||||
except UnboundLocalError as E:
|
except UnboundLocalError as E:
|
||||||
soundID, _X = (
|
soundID, _X = (
|
||||||
perc_inst_to_soundID_withX(-1)
|
perc_inst_to_soundID_withX(-1)
|
||||||
if SpecialBits
|
if SpecialBits
|
||||||
else inst_to_souldID_withX(-1)
|
else inst_to_sould_with_deviation(-1)
|
||||||
)
|
)
|
||||||
score_now = round(msg[-1] / float(speed) / 50)
|
score_now = round(msg[-1] / float(speed) / 50)
|
||||||
# print(score_now)
|
# print(score_now)
|
||||||
|
@ -20,6 +20,7 @@ from .main import MidiConvert, mido
|
|||||||
from .subclass import *
|
from .subclass import *
|
||||||
from .types import ChannelType
|
from .types import ChannelType
|
||||||
from .utils import *
|
from .utils import *
|
||||||
|
from .constants import *
|
||||||
|
|
||||||
|
|
||||||
class ObsoleteMidiConvert(MidiConvert):
|
class ObsoleteMidiConvert(MidiConvert):
|
||||||
@ -153,9 +154,9 @@ class ObsoleteMidiConvert(MidiConvert):
|
|||||||
)
|
)
|
||||||
maxscore = max(maxscore, nowscore)
|
maxscore = max(maxscore, nowscore)
|
||||||
if msg.channel == 9:
|
if msg.channel == 9:
|
||||||
soundID, _X = perc_inst_to_soundID_withX(instrumentID)
|
soundID, _X = inst_to_sould_with_deviation(instrumentID,MM_CLASSIC_PERCUSSION_INSTRUMENT_TABLE)
|
||||||
else:
|
else:
|
||||||
soundID, _X = inst_to_souldID_withX(instrumentID)
|
soundID, _X = inst_to_sould_with_deviation(instrumentID,MM_CLASSIC_PITCHED_INSTRUMENT_TABLE)
|
||||||
|
|
||||||
singleTrack.append(
|
singleTrack.append(
|
||||||
"execute @a[scores={"
|
"execute @a[scores={"
|
||||||
@ -212,7 +213,10 @@ class ObsoleteMidiConvert(MidiConvert):
|
|||||||
(ticks * tempo) / ((self.midi.ticks_per_beat * float(speed)) * 50000) # type: ignore
|
(ticks * tempo) / ((self.midi.ticks_per_beat * float(speed)) * 50000) # type: ignore
|
||||||
)
|
)
|
||||||
maxscore = max(maxscore, nowscore)
|
maxscore = max(maxscore, nowscore)
|
||||||
soundID, _X = inst_to_souldID_withX(instrumentID)
|
if msg.channel == 9:
|
||||||
|
soundID, _X = inst_to_sould_with_deviation(instrumentID,MM_CLASSIC_PERCUSSION_INSTRUMENT_TABLE)
|
||||||
|
else:
|
||||||
|
soundID, _X = inst_to_sould_with_deviation(instrumentID,MM_CLASSIC_PITCHED_INSTRUMENT_TABLE)
|
||||||
singleTrack.append(
|
singleTrack.append(
|
||||||
"execute @a[scores={"
|
"execute @a[scores={"
|
||||||
+ str(scoreboardname)
|
+ str(scoreboardname)
|
||||||
@ -273,9 +277,9 @@ class ObsoleteMidiConvert(MidiConvert):
|
|||||||
|
|
||||||
elif msg[0] == "NoteS":
|
elif msg[0] == "NoteS":
|
||||||
soundID, _X = (
|
soundID, _X = (
|
||||||
perc_inst_to_soundID_withX(msg[1])
|
inst_to_sould_with_deviation(msg[1],MM_CLASSIC_PERCUSSION_INSTRUMENT_TABLE)
|
||||||
if SpecialBits
|
if SpecialBits
|
||||||
else inst_to_souldID_withX(InstID)
|
else inst_to_sould_with_deviation(InstID,MM_CLASSIC_PITCHED_INSTRUMENT_TABLE)
|
||||||
)
|
)
|
||||||
score_now = round(msg[-1] / float(speed) / 50)
|
score_now = round(msg[-1] / float(speed) / 50)
|
||||||
maxScore = max(maxScore, score_now)
|
maxScore = max(maxScore, score_now)
|
||||||
@ -339,7 +343,11 @@ class ObsoleteMidiConvert(MidiConvert):
|
|||||||
(ticks * tempo)
|
(ticks * tempo)
|
||||||
/ ((self.midi.ticks_per_beat * float(speed)) * 50000)
|
/ ((self.midi.ticks_per_beat * float(speed)) * 50000)
|
||||||
)
|
)
|
||||||
soundID, _X = inst_to_souldID_withX(instrumentID)
|
|
||||||
|
if msg.channel == 9:
|
||||||
|
soundID, _X = inst_to_sould_with_deviation(instrumentID,MM_CLASSIC_PERCUSSION_INSTRUMENT_TABLE)
|
||||||
|
else:
|
||||||
|
soundID, _X = inst_to_sould_with_deviation(instrumentID,MM_CLASSIC_PITCHED_INSTRUMENT_TABLE)
|
||||||
try:
|
try:
|
||||||
tracks[now_tick].append(
|
tracks[now_tick].append(
|
||||||
self.execute_cmd_head.format(player)
|
self.execute_cmd_head.format(player)
|
||||||
@ -413,9 +421,9 @@ class ObsoleteMidiConvert(MidiConvert):
|
|||||||
|
|
||||||
elif msg[0] == "NoteS":
|
elif msg[0] == "NoteS":
|
||||||
soundID, _X = (
|
soundID, _X = (
|
||||||
perc_inst_to_soundID_withX(msg[1])
|
inst_to_sould_with_deviation(msg[1],MM_CLASSIC_PERCUSSION_INSTRUMENT_TABLE)
|
||||||
if SpecialBits
|
if SpecialBits
|
||||||
else inst_to_souldID_withX(InstID)
|
else inst_to_sould_with_deviation(InstID,MM_CLASSIC_PITCHED_INSTRUMENT_TABLE)
|
||||||
)
|
)
|
||||||
score_now = round(msg[-1] / float(speed) / 50)
|
score_now = round(msg[-1] / float(speed) / 50)
|
||||||
|
|
||||||
|
@ -18,10 +18,9 @@ Terms & Conditions: License.md in the root directory
|
|||||||
|
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Optional
|
from typing import Optional, Any
|
||||||
|
|
||||||
from .constants import PERCUSSION_INSTRUMENT_LIST
|
from .constants import MC_PERCUSSION_INSTRUMENT_LIST
|
||||||
from .utils import inst_to_souldID_withX, perc_inst_to_soundID_withX, volume2distance
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(init=False)
|
@dataclass(init=False)
|
||||||
@ -49,6 +48,9 @@ class SingleNote:
|
|||||||
percussive: bool
|
percussive: bool
|
||||||
"""是否为打击乐器"""
|
"""是否为打击乐器"""
|
||||||
|
|
||||||
|
extra_info: Any
|
||||||
|
"""你觉得放什么好?"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
instrument: int,
|
instrument: int,
|
||||||
@ -58,6 +60,7 @@ class SingleNote:
|
|||||||
lastime: int,
|
lastime: int,
|
||||||
track_number: int = 0,
|
track_number: int = 0,
|
||||||
is_percussion: Optional[bool] = None,
|
is_percussion: Optional[bool] = None,
|
||||||
|
extra_information: Any = None,
|
||||||
):
|
):
|
||||||
"""用于存储单个音符的类
|
"""用于存储单个音符的类
|
||||||
:param instrument 乐器编号
|
:param instrument 乐器编号
|
||||||
@ -80,12 +83,14 @@ class SingleNote:
|
|||||||
"""音符所处的音轨"""
|
"""音符所处的音轨"""
|
||||||
|
|
||||||
self.percussive = (
|
self.percussive = (
|
||||||
(is_percussion in PERCUSSION_INSTRUMENT_LIST)
|
(is_percussion in MC_PERCUSSION_INSTRUMENT_LIST)
|
||||||
if (is_percussion is None)
|
if (is_percussion is None)
|
||||||
else is_percussion
|
else is_percussion
|
||||||
)
|
)
|
||||||
"""是否为打击乐器"""
|
"""是否为打击乐器"""
|
||||||
|
|
||||||
|
self.extra_info = extra_information
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def inst(self) -> int:
|
def inst(self) -> int:
|
||||||
"""乐器编号"""
|
"""乐器编号"""
|
||||||
@ -100,14 +105,14 @@ class SingleNote:
|
|||||||
"""音符编号"""
|
"""音符编号"""
|
||||||
return self.note
|
return self.note
|
||||||
|
|
||||||
@property
|
# @property
|
||||||
def get_mc_pitch(self) -> float:
|
# def get_mc_pitch(self,table: Dict[int, Tuple[str, int]]) -> float:
|
||||||
self.mc_sound_ID, _X = (
|
# self.mc_sound_ID, _X = inst_to_sould_with_deviation(self.inst,table,"note.bd" if self.percussive else "note.flute",)
|
||||||
perc_inst_to_soundID_withX(self.inst)
|
# return -1 if self.percussive else 2 ** ((self.note - 60 - _X) / 12)
|
||||||
if self.percussive
|
|
||||||
else inst_to_souldID_withX(self.inst)
|
def set_info(self, sth: Any):
|
||||||
)
|
"""设置附加信息"""
|
||||||
return -1 if self.percussive else 2 ** ((self.note - 60 - _X) / 12)
|
self.extra_info = sth
|
||||||
|
|
||||||
def __str__(self, is_track: bool = False):
|
def __str__(self, is_track: bool = False):
|
||||||
return "{}Note(Instrument = {}, {}Velocity = {}, StartTime = {}, Duration = {}{})".format(
|
return "{}Note(Instrument = {}, {}Velocity = {}, StartTime = {}, Duration = {}{})".format(
|
||||||
@ -168,31 +173,6 @@ class SingleNote:
|
|||||||
return False
|
return False
|
||||||
return self.__str__() == other.__str__()
|
return self.__str__() == other.__str__()
|
||||||
|
|
||||||
def to_command(self, volume_percentage: float = 1) -> str:
|
|
||||||
"""
|
|
||||||
将音符转为播放的指令
|
|
||||||
:param volume_percentage:int 音量占比(0,1]
|
|
||||||
|
|
||||||
:return str指令
|
|
||||||
"""
|
|
||||||
self.mc_sound_ID, _X = (
|
|
||||||
perc_inst_to_soundID_withX(self.inst)
|
|
||||||
if self.percussive
|
|
||||||
else inst_to_souldID_withX(self.inst)
|
|
||||||
)
|
|
||||||
|
|
||||||
# delaytime_now = round(self.start_time / float(speed) / 50)
|
|
||||||
self.mc_pitch = "" if self.percussive else 2 ** ((self.note - 60 - _X) / 12)
|
|
||||||
|
|
||||||
self.mc_distance_volume = volume2distance(self.velocity * volume_percentage)
|
|
||||||
|
|
||||||
return "playsound {} @s ^ ^ ^{} {} {}".format(
|
|
||||||
self.mc_sound_ID,
|
|
||||||
self.mc_distance_volume,
|
|
||||||
volume_percentage,
|
|
||||||
self.mc_pitch,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(init=False)
|
@dataclass(init=False)
|
||||||
class SingleCommand:
|
class SingleCommand:
|
||||||
@ -304,7 +284,7 @@ class SingleNoteBox:
|
|||||||
self.annotation_text = annotation
|
self.annotation_text = annotation
|
||||||
"""音符注释"""
|
"""音符注释"""
|
||||||
if percussion is None:
|
if percussion is None:
|
||||||
self.is_percussion = percussion in PERCUSSION_INSTRUMENT_LIST
|
self.is_percussion = percussion in MC_PERCUSSION_INSTRUMENT_LIST
|
||||||
else:
|
else:
|
||||||
self.is_percussion = percussion
|
self.is_percussion = percussion
|
||||||
|
|
||||||
|
@ -16,9 +16,12 @@ Terms & Conditions: License.md in the root directory
|
|||||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
# 若需转载或借鉴 许可声明请查看仓库目录下的 License.md
|
||||||
|
|
||||||
import math
|
import math
|
||||||
|
import random
|
||||||
|
|
||||||
from .constants import PERCUSSION_INSTRUMENT_TABLE, PITCHED_INSTRUMENT_TABLE
|
from .constants import MM_INSTRUMENT_DEVIATION_TABLE, MC_INSTRUMENT_BLOCKS_TABLE
|
||||||
from typing import Any, Dict, Tuple
|
from .subclass import SingleNote
|
||||||
|
|
||||||
|
from typing import Any, Dict, Tuple, Optional, Callable, Literal, Union
|
||||||
|
|
||||||
|
|
||||||
def mctick2timestr(mc_tick: int) -> str:
|
def mctick2timestr(mc_tick: int) -> str:
|
||||||
@ -42,8 +45,11 @@ def empty_midi_channels(channel_count: int = 17, staff: Any = {}) -> Dict[int, A
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def inst_to_souldID_withX(
|
def inst_to_sould_with_deviation(
|
||||||
instrumentID: int,
|
instrumentID: int,
|
||||||
|
reference_table: Dict[int, Tuple[str, int]],
|
||||||
|
default_instrument: str = "note.flute",
|
||||||
|
default_deviation: Optional[int] = 5,
|
||||||
) -> Tuple[str, int]:
|
) -> Tuple[str, int]:
|
||||||
"""
|
"""
|
||||||
返回midi的乐器ID对应的我的世界乐器名,对于音域转换算法,如下:
|
返回midi的乐器ID对应的我的世界乐器名,对于音域转换算法,如下:
|
||||||
@ -60,40 +66,30 @@ def inst_to_souldID_withX(
|
|||||||
----------
|
----------
|
||||||
instrumentID: int
|
instrumentID: int
|
||||||
midi的乐器ID
|
midi的乐器ID
|
||||||
|
reference_table: Dict[int, Tuple[str, int]]
|
||||||
|
转换乐器参照表
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
tuple(str我的世界乐器名, int转换算法中的X)
|
tuple(str我的世界乐器名, int转换算法中的X)
|
||||||
"""
|
"""
|
||||||
try:
|
return reference_table.get(
|
||||||
return PITCHED_INSTRUMENT_TABLE[instrumentID]
|
instrumentID,
|
||||||
except KeyError:
|
(
|
||||||
return "note.flute", 5
|
default_instrument,
|
||||||
|
default_deviation
|
||||||
|
if default_deviation
|
||||||
def perc_inst_to_soundID_withX(instrumentID: int) -> Tuple[str, int]:
|
else MM_INSTRUMENT_DEVIATION_TABLE.get(default_instrument, -1),
|
||||||
"""
|
),
|
||||||
对于Midi第10通道所对应的打击乐器,返回我的世界乐器名
|
)
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
instrumentID: int
|
|
||||||
midi的乐器ID
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
tuple(str我的世界乐器名, int转换算法中的X)
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
return PERCUSSION_INSTRUMENT_TABLE[instrumentID]
|
|
||||||
except KeyError:
|
|
||||||
return "note.bd", 7
|
|
||||||
|
|
||||||
# 明明已经走了
|
# 明明已经走了
|
||||||
# 凭什么还要在我心里留下缠绵缱绻
|
# 凭什么还要在我心里留下缠绵缱绻
|
||||||
|
|
||||||
|
|
||||||
def volume2distance(vol: float) -> float:
|
def natural_curve(
|
||||||
|
vol: float,
|
||||||
|
) -> float:
|
||||||
"""
|
"""
|
||||||
midi力度值拟合成的距离函数
|
midi力度值拟合成的距离函数
|
||||||
|
|
||||||
@ -117,3 +113,97 @@ def volume2distance(vol: float) -> float:
|
|||||||
+ -6.313841334963396 * (vol + 2592.272889454798)
|
+ -6.313841334963396 * (vol + 2592.272889454798)
|
||||||
+ 4558.496367823575
|
+ 4558.496367823575
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def straight_line(vol: float) -> float:
|
||||||
|
"""
|
||||||
|
midi力度值拟合成的距离函数
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
vol: int
|
||||||
|
midi音符力度值
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
float播放中心到玩家的距离
|
||||||
|
"""
|
||||||
|
return vol / -8 + 16
|
||||||
|
|
||||||
|
|
||||||
|
def note_to_command_parameters(
|
||||||
|
note_: SingleNote,
|
||||||
|
reference_table: Dict[int, Tuple[str, int]],
|
||||||
|
volume_percentage: float = 1,
|
||||||
|
volume_processing_method: Callable[[float], float] = natural_curve,
|
||||||
|
) -> Tuple[str, float, float, Union[float, Literal[None]],]:
|
||||||
|
"""
|
||||||
|
将音符转为播放的指令
|
||||||
|
:param note_:int 音符对象
|
||||||
|
:param reference_table:Dict[int, Tuple[str, int]] 转换对照表
|
||||||
|
:param volume_percentage:int 音量占比(0,1]
|
||||||
|
:param volume_proccessing_method:Callable[[float], float]: 音量处理函数
|
||||||
|
|
||||||
|
:return str[我的世界音符ID], float[播放距离], float[指令音量参数], float[指令音调参数]
|
||||||
|
"""
|
||||||
|
mc_sound_ID, deviation = inst_to_sould_with_deviation(
|
||||||
|
note_.inst,
|
||||||
|
reference_table,
|
||||||
|
"note.bd" if note_.percussive else "note.flute",
|
||||||
|
)
|
||||||
|
|
||||||
|
# delaytime_now = round(self.start_time / float(speed) / 50)
|
||||||
|
mc_pitch = None if note_.percussive else 2 ** ((note_.note - 60 - deviation) / 12)
|
||||||
|
|
||||||
|
mc_distance_volume = volume_processing_method(note_.velocity * volume_percentage)
|
||||||
|
|
||||||
|
return mc_sound_ID, mc_distance_volume, volume_percentage, mc_pitch
|
||||||
|
|
||||||
|
|
||||||
|
def from_single_note(
|
||||||
|
note_: SingleNote, random_select: bool = False, default_block: str = "air"
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
将我的世界乐器名改作音符盒所需的对应方块名称
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
note_: SingleNote
|
||||||
|
音符类
|
||||||
|
random_select: bool
|
||||||
|
是否随机选取对应方块
|
||||||
|
default_block: str
|
||||||
|
查表查不到怎么办?默认一个!
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
str方块名称
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
# return SingleNoteBox() # TO-DO
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def soundID_to_blockID(
|
||||||
|
sound_id: str, random_select: bool = False, default_block: str = "air"
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
将我的世界乐器名改作音符盒所需的对应方块名称
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
sound_id: str
|
||||||
|
将我的世界乐器名
|
||||||
|
random_select: bool
|
||||||
|
是否随机选取对应方块
|
||||||
|
default_block: str
|
||||||
|
查表查不到怎么办?默认一个!
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
str方块名称
|
||||||
|
"""
|
||||||
|
if random_select:
|
||||||
|
return random.choice(MC_INSTRUMENT_BLOCKS_TABLE.get(sound_id, (default_block,)))
|
||||||
|
else:
|
||||||
|
return MC_INSTRUMENT_BLOCKS_TABLE.get(sound_id, (default_block,))[0]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user