如何消除Music21生成的MusicXML文件结尾的空白小节?
解决Music21生成MusicXML后MuseScore显示大量空白小节的问题
我正在使用Music21制作乐谱,生成MusicXML文件后在MuseScore中打开,发现乐谱末尾在我添加的音符之后有大量空白小节。尝试过写函数删除空白区域或移除末尾休止符,但问题似乎出在声部插入乐谱的环节。
原代码:
!pip install music21 from music21 import * score = stream.Score() part1 = stream.Part() part2 = stream.Part() part1.append(instrument.Violoncello()) part2.append(instrument.Viola()) part1.append(meter.TimeSignature('4/4')) # Define the time signature part2.append(meter.TimeSignature('4/4')) # Define the time signature # Add 10 measures with notes in the first part for i in range(100): # Add some random notes for each measure part1.append(note.Note('C4', quarterLength=1)) part1.append(note.Rest(quarterLength=1)) part1.append(note.Note('E4', quarterLength=1)) part1.append(note.Rest(quarterLength=1)) part1.append(note.Note('G4', quarterLength=1)) part1.append(note.Note('C5', quarterLength=1)) # Add 10 measures with notes in the second part for i in range(100): # Add some random notes for each measure part2.append(note.Note('C3', quarterLength=1)) part2.append(note.Note('E3', quarterLength=1)) part2.append(note.Rest(quarterLength=1)) part2.append(note.Note('G3', quarterLength=1)) part2.append(note.Note('C4', quarterLength=1)) # Create the combined score score.append(part1) score.append(part2) # Save the combined score score.write('musicxml', fp='combined_score.musicxml')
问题根源
- 未明确创建**小节(Measure)**对象,Music21会自动根据声部总时长补全到规整的小节数,催生多余空白。
- 两个声部的单循环时长不匹配:第一声部每次循环添加6拍内容,第二声部是5拍,总时长不一致后,Music21会以最长声部为准补全,进一步放大空白问题。
解决方法
方法1:手动创建Measure对象(最稳妥)
明确划分每个小节,确保每个小节时长符合拍号要求,且两个声部的小节数、时长完全一致:
!pip install music21 from music21 import * score = stream.Score() part1 = stream.Part() part2 = stream.Part() part1.append(instrument.Violoncello()) part2.append(instrument.Viola()) time_sig = meter.TimeSignature('4/4') part1.append(time_sig) part2.append(time_sig) # 循环创建100个小节,每个小节严格符合4/4拍(4拍) for i in range(100): # 第一声部的小节 m1 = stream.Measure(number=i+1) m1.append(note.Note('C4', quarterLength=1)) m1.append(note.Rest(quarterLength=1)) m1.append(note.Note('E4', quarterLength=1)) m1.append(note.Note('G4', quarterLength=1)) # 调整后总时长为4拍,符合4/4 part1.append(m1) # 第二声部的小节 m2 = stream.Measure(number=i+1) m2.append(note.Note('C3', quarterLength=1)) m2.append(note.Note('E3', quarterLength=1)) m2.append(note.Rest(quarterLength=1)) m2.append(note.Note('G3', quarterLength=1)) # 调整后总时长为4拍,符合4/4 part2.append(m2) score.append(part1) score.append(part2) score.write('musicxml', fp='combined_score.musicxml')
方法2:自动生成小节(快速修复)
如果不想手动调整每个小节的内容,可以用makeMeasures()方法自动划分小节,但需确保两个声部的总时长是拍号的整数倍:
在原代码中,先调整两个声部的单循环时长一致(比如都改成4拍),然后在添加声部到乐谱前执行:
# 自动划分小节 part1.makeMeasures(inPlace=True) part2.makeMeasures(inPlace=True)
这样Music21会根据拍号自动把内容划分成规整的小节,避免多余空白。
内容的提问来源于stack exchange,提问作者cirogalvao
相关产品推荐
相关产品推荐

