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

如何消除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')

问题根源

  1. 未明确创建**小节(Measure)**对象,Music21会自动根据声部总时长补全到规整的小节数,催生多余空白。
  2. 两个声部的单循环时长不匹配:第一声部每次循环添加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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 02:59:58