如何使用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
相关产品推荐
相关产品推荐

