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

如何使用music21从MIDI文件提取音符、音高或时值数组?

使用music21提取MIDI中的音符、音高及时值数组

1. 基础准备:加载MIDI文件到Stream

先确保你已经正确加载MIDI文件到Stream对象:

from music21 import midi, chord

# 替换为你的长笛MIDI文件路径
stream_obj = midi.translate.midiFileToStream("your_flute_midi.mid")

2. 提取音符对象数组

Stream可能存在嵌套结构,用flat方法扁平化后,直接获取所有音符(包含和弦):

# 获取所有音符对象(包括和弦)
notes_list = list(stream_obj.flat.notes)

# 若只需单音(长笛作品通常以单音为主),过滤掉和弦
single_notes = [n for n in notes_list if not isinstance(n, chord.Chord)]

3. 提取音高数组

可以根据需求提取音名字符串或MIDI音高编号:

# 提取音名字符串数组(如 ["C4", "D#4", ...])
pitch_names = [n.pitch.nameWithOctave for n in single_notes]

# 提取MIDI音高编号数组(如 [60, 63, ...])
pitch_numbers = [n.pitch.midi for n in single_notes]

4. 提取音符时值数组

时值以四分音符为单位(四分音符时值为1,八分音符为0.5,二分音符为2等):

durations = [n.duration.quarterLength for n in single_notes]

5. 整合为结构化数组

如果需要把音高、时值整合为更易处理的结构化数据:

note_details = [
    {
        "pitch_name": n.pitch.nameWithOctave,
        "pitch_midi": n.pitch.midi,
        "duration": n.duration.quarterLength
    } for n in single_notes
]

处理和弦(若存在)

如果你的MIDI中包含和弦,可提取和弦内的每个音并保留对应时值:

all_note_details = []
for elem in stream_obj.flat.notes:
    if isinstance(elem, chord.Chord):
        # 遍历和弦中的每个音
        for pitch in elem.pitches:
            all_note_details.append({
                "pitch_name": pitch.nameWithOctave,
                "pitch_midi": pitch.midi,
                "duration": elem.duration.quarterLength
            })
    else:
        all_note_details.append({
            "pitch_name": elem.pitch.nameWithOctave,
            "pitch_midi": elem.pitch.midi,
            "duration": elem.duration.quarterLength
        })

内容的提问来源于stack exchange,提问作者Mader n fader

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 14:42:44