from midiutil import MIDIFile
# 音符映射保持不变(同原代码)
note_map = {
# 低音区、中音区、高音区映射...
'1.': 48, '2.': 50, '3.': 52, '4.': 53, '5.': 55, '6.': 57, '7.': 59,
'1..': 36, '2..': 38, '3..': 40, '4..': 41, '5..': 43, '6..': 45, '7..': 47,
'1...': 24, '2...': 26, '3...': 28, '4...': 29, '5...': 31, '6...': 33, '7...': 35,
'1': 60, '2': 62, '3': 64, '4': 65, '5': 67, '6': 69, '7': 71,
'1*': 72, '2*': 74, '3*': 76, '4*': 77, '5*': 79, '6*': 81, '7*': 83,
'1**': 84, '2**': 86, '3**': 88, '4**': 89, '5**': 91, '6**': 93, '7**': 95,
'1***': 96, '2***': 98, '3***': 100, '4***': 101, '5***': 103, '6***': 105, '7***': 107,
'0': None, '-': None
}
# 定义简谱段落(修正格式并解析横杠)
simple_score_str = "116.132---1335.7.6.----17.6.6.1235.---5.5.5.3.53----326.-132---1335.7.6.----17.6.6.3312--133236.---356--365--565323--3216132---355512----356--365--565563---3216.1235.5.-3.5.5.7.6.----356---365---565353----3216.1235.-3.5.5.5.3.7.6.---"
# 解析简谱字符串为(音符, 时值)列表
def parse_score(s):
score = []
i = 0
while i < len(s):
if s[i] == '-':
# 处理休止符或延长符(连续横杠为延长时值)
j = i
while j < len(s) and s[j] == '-':
j += 1
duration = j - i # 横杠数量即延长拍数
score.append(('-', duration))
i = j
else:
# 处理音符(数字+*或.)
j = i + 1
while j < len(s) and s[j] in ['.', '*']:
j += 1
note = s[i:j]
# 计算音符后的横杠时值(延长部分)
k = j
while k < len(s) and s[k] == '-':
k += 1
duration = 1 + (k - j) # 音符本身1拍,横杠每根+1拍
score.append((note, duration))
i = k
return score
# 解析后的简谱列表
simple_score = parse_score(simple_score_str)
# 生成MIDI的函数(保持不变)
def generate_midi(score, output_file="盗将行.mid", tempo=120, channel=1, program=11):
midi = MIDIFile(numTracks=1)
midi.addTempo(0, 0, tempo)
# 关键:设置乐器(program为乐器编号,channel为通道)
midi.addProgramChange(0, channel, 0, program)
time = 0
for note_str, duration in score:
if note_str in ['0', '-']:
time += duration
continue
midi_pitch = note_map.get(note_str)
if not midi_pitch:
print(f"警告:未知音符 {note_str},跳过")
continue
midi.addNote(
0, channel, midi_pitch,
time, duration, 80
)
time += duration
with open(output_file, "wb") as f:
midi.writeFile(f)
print(f"MIDI文件生成成功:{output_file}")
# 调用时指定program和channel
generate_midi(simple_score, tempo=220, channel=1, program=0)
04-22
792
