拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Audiveris 小节重复记号(Bar Repeat)识别、编辑与 MusicXML 导出实战指南

Audiveris 小节重复记号(Bar Repeat)识别、编辑与 MusicXML 导出实战指南
  • 桌面应用
  • 计算机视觉
  • 图像处理
  • OCR

【免费下载链接】audiveris

Latest generation of Audiveris OMR engine

项目地址:https://gitcode.com/gh_mirrors/au/audiveris
点击查看免费下载

小节重复记号(bar repeat)是乐谱中常见的一类缩写记号,用于指示"前面已写出的若干小节必须原样重复"。本文以 Audiveris OMR 引擎为对象,系统讲解该引擎自 release 5.3 起对 1、2、4 斜杠小节重复记号及其上方可选小节计数的识别模型、形状面板手工编辑流程,以及 MusicXML 导出时的具体行为,并结合仓库源码给出可验证的实现依据。读完本文,你将能够在 Audiveris 中正确识别、修正并导出包含小节重复记号的乐谱。

小节重复记号在整页乐谱中的真实分布示例(图片源自 bar_repeats.png)

一、什么是小节重复记号

在乐谱记谱法中,**小节重复记号(bar repeat / measure repeat)**表示"其前方已经写出的若干小节必须被原样重复"。它通常以带斜杠的记号形态出现在小节内部或小节线上方:

  • 记号的斜杠数量(1、2 或 4)决定了要重复的前置小节数量;
  • 记号上方可选的小节计数(如数字"2")进一步明确重复范围,在规范记谱中应与斜杠数量一致。

在 Audiveris 的源码中,这一语义被直接固化在形状定义里。打开 Shape.java 可以看到三个核心逻辑形状:

REPEAT_ONE_BAR("Repeat last bar"), REPEAT_TWO_BARS("Repeat last two bars"), REPEAT_FOUR_BARS("Repeat last four bars"),

对应的斜杠数量由 Shape.getSlashCount() 统一返回:

public int getSlashCount () { return switch (this) { case REPEAT_ONE_BAR -> 1; case REPEAT_TWO_BARS -> 2; case REPEAT_FOUR_BARS -> 4; default -> 0; }; }

可见"斜杠数 = 重复小节数"这一对应关系是引擎识别与导出的基础约定。

二、示例解读:一个、两个与四个小节重复

先看上文整页示例(bar_repeats.png)所描述的场景:

  • 全曲包含两个系统(system):第一个系统有 4 个小节(#1、#2、#3、#4),第二个系统有 3 个小节(#5、#6、#7);
  • 第一个系统中,小节 #2 和 #3 内部各有一个单小节重复记号(one-bar repeat),其含义是"重复小节 #1 两次",即 #2 重复 #1、#3 再重复 #1;
  • 第二个系统中,小节 #6 与 #7 之间的小节线上方出现一个两小节重复记号(two-bar repeat),表示重复其前方两个小节(#4 和 #5),即 #6、#7 的内容分别等于 #4、#5;
  • 同理,还可能遇到四小节重复记号(four-bar repeat),用于重复前方四个小节。

也就是说,一个重复记号实际"吃掉"了斜杠数量个物理小节,这些小节在谱面上不必再写出完整音符,但在导出的结果中会被展开成真实内容(详见第五节)。

三、识别模型:从形状到符号解释

3.1 识别能力(release 5.3 起)

根据官方文档,Audiveris OMR 引擎自 release 5.3 起能够自动识别两类信息:

  1. 重复记号本身,支持 1、2 或 4 条斜杠三种形态;
  2. 记号上方的可选小节计数,该计数应与其斜杠数量一致。

文档中的bar_repeat_2.png展示了带计数与不带计数的典型形态:

单小节重复记号的两种形态:是否携带上方小节计数(图片源自 bar_repeat_2.png)

3.2 形状集合的归属

在 ShapeSet.java 中,三个重复记号形状被归入RepeatBars列表:

/** Repeat bars. */ public static final List<Shape> RepeatBars = Arrays.asList( REPEAT_ONE_BAR, REPEAT_TWO_BARS, REPEAT_FOUR_BARS);

而 Barlines 形状集合(即形状面板中的Barlines组)则把常规小节线、反复号(左右反复/背靠背反复)、花括号、括号、反复点(REPEAT_DOT)与上述RepeatBars全部收纳在一起,这正是文档所述"三个符号位于Barlines集合中"的源码出处。

用于标注重复小节数的计数形状则定义在 MeasureCounts 列表中,包含自定义数字NUMBER_CUSTOM以及TIME_ONE~TIME_EIGHT等时间样式数字;Times 集合由MeasureCounts、TIME_CUSTOM(自定义)与WholeTimes组成,对应文档所述"小节计数可从Times集合中选取"。

3.3 符号解释(Inter)与关系建模

自动识别时,InterFactory.java 会将识别出的三个形状统一实例化为MeasureRepeatInter:

// Measure repeat signs case REPEAT_ONE_BAR: case REPEAT_TWO_BARS: case REPEAT_FOUR_BARS: return MeasureRepeatInter.create(glyph, shape, grade, closestStaff); // Staff is OK

MeasureRepeatInter.java 是这一功能的符号解释核心类,其关键设计包括:

  • JAXB 根元素名称为measure-repeat,可直接序列化进工程文件;
  • 实例被added()后自动登记到所在MeasureStack(小节栈),remove()时同步从栈中移除,保证与节奏/小节体系联动;
  • 支持手动创建的构造函数(glyph为 null 的 ghost 对象),供形状面板拖放使用;
  • 编辑器为HorizontalEditor,拖放时通过deriveOnStaffMiddleLine将其定位到谱表中线,便于对齐。

小节重复记号与其上方计数之间的关联由 MeasureRepeatCountRelation.java 建模,其 JAXB 名称为measure-repeat-count,是Support类型的单源单目标关系;源码注释明确说明:重复记号本身并不强制要求计数,因为斜杠数已经表达了重复次数,计数仅作为补充信息。

在小节层面,Measure.java 用LinkedHashSet<MeasureRepeatInter> repeatSigns保存本小节内的重复记号,并对外提供只读视图 getMeasureRepeats()。值得一提的是,旧版本中曾使用SimileMarkInter(同前记号)表达此类语义,现已被repeatSigns取代,并在加载旧工程时通过 SimileMarkInter.replace() 自动迁移,体现了模型演进脉络。

四、手工编辑:从形状面板分配与拖放

当自动识别不理想(例如记号被误判、位置偏移)时,可以手动处理:

  1. 重复记号本身:从形状面板的Barlines集合中选择REPEAT_ONE_BAR、REPEAT_TWO_BARS或REPEAT_FOUR_BARS三个符号之一,手动分配(assign)或直接拖放到目标位置。面板形态见下图:

Barlines形状面板中的小节重复记号与相关符号(图片源自 bar_repeat_palette.png)

  1. 小节计数(可选):从形状面板的Times集合中选取。两种途径:
    • 选择Parts数字中的预定义项(如TIME_ONE~TIME_EIGHT等现成数字形状);
    • 或选择自定义0项(NUMBER_CUSTOM/TIME_CUSTOM),再手动输入所需数值。

注:Times面板截图见仓库中的 time_palette.png。计数并非必需——如前所述,斜杠数已隐含重复次数,计数应与其保持一致。

拖放/编辑过程由MeasureRepeatInter的getEditor()(返回HorizontalEditor)与deriveFrom()(定位到谱表中线)共同驱动,可参考 MeasureRepeatInter.java。若计数与记号建立了关联,MeasureRepeatCountRelation会在关系增删时对其执行异常检查(checkAbnormal),帮助及时发现不一致。

五、MusicXML 输出行为

5.1 导出逻辑

Audiveris 的 MusicXML 导出器在 PartwiseBuilder.java 中处理小节重复记号,其核心流程是:

  1. 若当前小节带有重复记号(repeats非空),取记号形状的斜杠数slashes;
  2. 在小节属性中插入<measure-repeat>元素,写入slashes与type="start":
final MeasureStyle measureStyle = factory.createMeasureStyle(); final MeasureRepeat repeat = factory.createMeasureRepeat(); repeat.setSlashes(new BigInteger("" + slashes)); repeat.setType(StartStop.START); measureStyle.setMeasureRepeat(repeat); getAttributes().getMeasureStyle().add(measureStyle);
  1. 随后向前回溯slashes个不含重复记号的前置小节(getPrecedingInScore()逐级前移),若中途遇到另一个重复记号且尚未收集到内容,则记录告警"Abnormal measure sequence before repeat sign"并安全终止;
  2. 将回溯到的小节按逻辑内容逐一复制展开,每个斜杠对应一个小节,展开小节的编号形如stack.getScoreId(...) + "+" + (i + 1)(例如4+1、4+2)。

源码中// TODO: take into account the number symbol if any above the measure repeat sign表明:当前版本导出时以斜杠数为准复制展开小节,记号上方的小节计数暂未参与展开计算,这一点在实际使用时需要注意。

5.2 显示与播放的已知差异

文档明确记录了在不同软件中观察到的行为差异,这是导出后验证的重要参考:

  • 显示方面:
    • 使用Finale(版本 27)读取时,重复记号按预期显示;
    • 使用MuseScore(版本 3.6.2)读取时,重复记号本身不显示,但被重复的小节如同被"物理复制"一样完整呈现;
  • 播放方面:
    • 无论 Finale 还是 MuseScore,重复小节都能正确发声,即播放效果符合乐谱意图。

换言之,Audiveris 导出的 MusicXML 在语义上是正确的(播放无误),差异主要出现在部分阅读器对<measure-repeat>元素的可视化支持程度不同。

六、小结

小节重复记号是 Audiveris 自 release 5.3 起完整支持的记谱元素,其技术链路清晰可查:

环节载体说明
形状定义Shape.javaREPEAT_ONE_BAR/REPEAT_TWO_BARS/REPEAT_FOUR_BARS
斜杠计数Shape.getSlashCount()返回 1、2、4
面板分组ShapeSet.javaBarlines集合(含RepeatBars)与Times集合
自动识别InterFactory.java实例化MeasureRepeatInter
符号解释MeasureRepeatInter.java与小节栈联动、支持手动编辑
计数关系MeasureRepeatCountRelation.java记号与计数的一对一关联
MusicXML 导出PartwiseBuilder.java写入<measure-repeat>并复制展开前置小节

实操建议:识别完成后,先核对记号斜杠数是否符合预期;如需要计数标注,从Times集合选取预定义数字或自定义值;导出 MusicXML 后,在 Finale 中检查记号显示,在 MuseScore 中核对小节是否被正确展开,并以播放验证语义完整性。

  • 桌面应用
  • 计算机视觉
  • 图像处理
  • OCR

【免费下载链接】audiveris

Latest generation of Audiveris OMR engine

项目地址:https://gitcode.com/gh_mirrors/au/audiveris
点击查看免费下载

相关推荐

上一篇:终极Yuzu模拟器下载指南:三步获取最佳版本体验
下一篇:ng-zorro-antd Tree View 教程:使用 nzChildrenAccessor 实现基本的选中、禁用与展开

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表