如何用music21分别统计乐谱第一小节高音、低音谱号的音符数?
用music21分别统计MIDI第一小节高音/低音谱号的音符数量
问题说明
手动计数目标MIDI第一小节的高音、低音谱号音符总数为23个,但原代码仅统计出19个,且对比小节截图发现部分音符未被识别,需要实现分别统计两类谱号的音符数量。
原代码问题分析
原代码仅统计了note.Note类型的元素,而MIDI文件中的和弦(Chord)会被视为单个元素,但和弦包含多个独立音符,这直接导致统计数量偏少。此外,原代码未区分对应高低音谱号的声部,无法实现分谱号统计。
解决方案
MIDI文件中,高音、低音谱号通常对应不同的声部(Part),钢琴类MIDI一般第0个声部对应高音谱号,第1个对应低音谱号。我们可以拆分声部后,递归遍历每个声部第一小节的所有音符(包括和弦内的音符),再分别统计数量。
代码实现
from music21 import converter, note, chord, stream # 解析MIDI文件 my_score = converter.parse('/Users/carlkonopka/Downloads/midi/music21.mid') # 定义声部对应的谱号名称 part_names = ['高音谱号', '低音谱号'] # 遍历每个声部 for idx, part in enumerate(my_score.parts): # 获取第一小节 measure_1 = part.measure(1) note_count = 0 # 递归遍历所有音符(包括和弦内的音符) for element in measure_1.recurse(): if isinstance(element, note.Note): note_count += 1 elif isinstance(element, chord.Chord): # 和弦的每个音都算一个独立音符 note_count += len(element.notes) print(f"{part_names[idx]}第一小节音符数量:{note_count}")
关键说明
- 声部拆分:通过
my_score.parts获取所有声部,钢琴MIDI默认两个声部分别对应高低音谱号 - 递归遍历:
recurse()会遍历小节内所有嵌套元素,包括和弦里的每个单独音符,避免遗漏 - 统计逻辑:区分单个音符和和弦,和弦按包含的音符数量累加,确保统计结果准确
内容的提问来源于stack exchange,提问作者carljong2003ctkctk
相关产品推荐
相关产品推荐

