You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用music21解析MIDI如何输出带八度号的正确等音拼写音高

解决方案

1. 稳定输出带八度编号的音高

你现有思路是对的,可优化为更稳定的写法,避免异常捕获的不严谨问题:

from music21 import *
environment.set('autoDownload', 'allow')

stream1 = converter.parse("你的MIDI文件路径")

# 遍历所有音符/和弦元素
for elem in stream1.recurse().notes:
    current_offset = elem.offset
    # 处理单个音符
    if isinstance(elem, note.Note):
        print(current_offset, elem.nameWithOctave)
    # 处理和弦
    elif isinstance(elem, chord.Chord):
        pitch_str = " ".join([p.nameWithOctave for p in elem.pitches])
        print(current_offset, pitch_str)

2. 修正等音拼写(适配调性语境)

EnharmonicSimplifier.bestPitches()支持批量处理全曲音高,你可以先提取全曲所有音高,统一修正后再映射回原元素输出,具体实现如下:

from music21.analysis import enharmonics

# 第一步:收集全曲所有元素与对应音高
elem_list = []
all_pitches = []
for elem in stream1.recurse().notes:
    elem_list.append(elem)
    if isinstance(elem, note.Note):
        all_pitches.append(elem.pitch)
    elif isinstance(elem, chord.Chord):
        all_pitches.extend(elem.pitches)

# 第二步:批量修正等音拼写
simplifier = enharmonics.EnharmonicSimplifier()
corrected_pitches = simplifier.bestPitches(all_pitches)

# 第三步:按原顺序输出修正后的结果
ptr = 0
for elem in elem_list:
    current_offset = elem.offset
    if isinstance(elem, note.Note):
        print(current_offset, corrected_pitches[ptr].nameWithOctave)
        ptr += 1
    elif isinstance(elem, chord.Chord):
        chord_pitches = corrected_pitches[ptr:ptr+len(elem.pitches)]
        pitch_str = " ".join([p.nameWithOctave for p in chord_pitches])
        print(current_offset, pitch_str)
        ptr += len(elem.pitches)

以上实现就能直接获取你需要的偏移时间、带八度编号、拼写正确的音高信息,不需要额外转换为其他格式。

内容的提问来源于stack exchange,提问作者ultraGentle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 13:18:03