强大的音乐乐谱控件库
2023 Conmajia, 2018 Ajcek84
SN: 23C.1
本中文翻译已获原作者首肯。
简介
PSAM 控件库——波兰音乐文档系统——是用于显示、排版乐谱的强大 WinForm 库,包含用于绘制乐谱的名为 IncipitViewer 控件,乐谱内容可以从 MusicXml 文件读取,或者在程序中添加赋格、音符、小节等。这个控件是为 PSAM 软件(图 1)而开发的组件。当我意识到其他软件开发者也许可能想要用到它的功能,我决定在 BSD 许可下发布这个控件。PSAM 控件库完全由 C# 实现。

使用代码
IncipitViewer 控件需要特殊的音乐字体来绘制音符等。本文提供的下载资源中附带了 Polihymnia 的 TrueType 字体,以便你可以直接安装使用。这个字体基于 Ben Laenen 的 Euterpe 字体,以 Sil 开放字体许可发布。
IncipitViewer(PSAMControlLibrary.dll)是标准的 C# 控件库。将其简单拖放至 Visual Studio 窗体设计器工具箱即可开始使用。控件用法类似普通控件,如 TextBox 等。若是用编程方式创建 IncipitViewer 控件,使用如下代码。
IncipitViewer viewer = new IncipitViewer();
viewer.Dock = DockStyle.Fill;
Controls.Add(viewer);
一般来说 Visual Studio 会自动添加
using PSAMControlLibrary;
本控件提供了从 MusicXML 文件读取乐谱的功能——仅限第一行谱表1,忽略后续谱表。
viewer.LoadFromXmlFile("example.xml");
从文件读取并显示乐谱效果如下。

使用 ClearMusicalIncipit() 方法可清除当前显示内容。
本控件提供了代码用于以编程方式添加音符等内容。例如,下面的代码向乐谱第 2 行添加了一个 G 谱号。
Clef c = new Clef(ClefType.GClef, 2);
viewer.AddMusicalSymbol(c);
以及一个新的 G 调四分音符(1=G4/4)。
Note n = new Note("G", 0, 4, MusicalSymbolDuration.Quarter,NoteStemDirection.Up, NoteTieType.None,new List<NoteBeamType>() {NoteBeamType.Single});
viewer.AddMusicalSymbol(n);
音符(Note)构造函数的第一个参数键名(A, B, C, D, E, F, G),第二个参数是升调数(+)或降调数(-)。升降调若为 0 则表示原调。第三个参数是八度。接下来的参数有:音符节拍、音杆方向和延音线类型(如果没有则为 NoteTieType.None)。最后一个参数是符杠列表。如果音符没有任何符杠,即使音符的持续时间大于八分音符,仍然需要有这个列表,只是里面仅有一个元素 NoteBeamType.Single。为了清楚地说明符杠列表是如何工作的,下面的代码将尝试添加一个由两个十六分音符和一个八分音符组成的组:
Note s1 = new Note("A", 0, 4, MusicalSymbolDuration.Sixteenth, NoteStemDirection.Down, NoteTieType.None,new List<NoteBeamType>() { NoteBeamType.Start, NoteBeamType.Start});
Note s2 = new Note("C", 1, 5, MusicalSymbolDuration.Sixteenth, NoteStemDirection.Down, NoteTieType.None,new List<NoteBeamType>() { NoteBeamType.Continue, NoteBeamType.End });
Note e = new Note("D", 0, 5, MusicalSymbolDuration.Eighth, NoteStemDirection.Down, NoteTieType.None,new List<NoteBeamType>() { NoteBeamType.End });
viewer.AddMusicalSymbol(s1);
viewer.AddMusicalSymbol(s2);
viewer.AddMusicalSymbol(e);
显示的乐谱如下。

如果设置符杠为 NoteBeamType.Single,则乐谱如下。

本控件还支持彩色音符,只需要简单地修改音符 MusicalCharacterColor 属性。

尽管 IncipitViewer 只支持单谱表,但它依然支持和弦,因为它们是许多单声部乐器习惯用法的一部分。如果一个音符的 IsChordElement 属性设置为 true,那么它就被视为前一个音符的和弦元素:
Note n1 = new Note("C", 0, 4, MusicalSymbolDuration.Half, NoteStemDirection.Up, NoteTieType.None,new List<NoteBeamType>() { NoteBeamType.Single });
Note n2 = new Note("E", 0, 4, MusicalSymbolDuration.Half, NoteStemDirection.Up, NoteTieType.None,new List<NoteBeamType>() { NoteBeamType.Single });
Note n3 = new Note("G", 0, 4, MusicalSymbolDuration.Half, NoteStemDirection.Up, NoteTieType.None,new List<NoteBeamType>() { NoteBeamType.Single });
n2.IsChordElement = true;
n3.IsChordElement = true;viewer.AddMusicalSymbol(n1);
viewer.AddMusicalSymbol(n2);
viewer.AddMusicalSymbol(n3);
结果如下。

下面的代码演示了点、休止符和小节符。
Note n4 = new Note("A", 0, 4, MusicalSymbolDuration.Half,NoteStemDirection.Up, NoteTieType.None,new List<NoteBeamType>() { NoteBeamType.Single });
n4.NumberOfDots = 1;
Rest r = new Rest(MusicalSymbolDuration.Quarter);
Barline b = new Barline();
viewer.AddMusicalSymbol(n4);
viewer.AddMusicalSymbol(r);
viewer.AddMusicalSymbol(b);
结果如下。

鼠标互动
当鼠标悬停在控件上时,右上角会出现两个按钮:第一个用于保存与控件关联的 MusicXml 文件,第二个用于调用 OnPlayExternalMidiPlayer 事件处理程序,用法如下。
viewer.PlayExternalMidiPlayer += new IncipitViewer.PlayExternalMidiPlayerDelegate(viewer_PlayExternalMidiPlayer);
void viewer_PlayExternalMidiPlayer(IncipitViewer sender) {//Place your code here
}
借此,你可以用代码从已有控件读出音符,并用自定义代码或是其他第三方库播放。IncipitViewer.IncipitElement(int i) 方法可以读取第 i 个音符,而 MusicalSymbol.ToMidiPitch() 方法则可以将空间中的音符转换为 MIDI。
要打印 IncipitViewer 控件的内容,创建一个 PrintDocument 对象并处理其 PrintPage 事件。
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) {Graphics g = e.Graphics;viewer.DrawViewer(g, true);
}
接下来调用 Print() 方法打印音乐文档。
PrintDialog dlg = new PrintDialog();
dlg.Document = printDocument1;
if (dlg.ShowDialog() == DialogResult.OK) {printDocument1.Print();
}
打印样张如下。

许可
本文及其附属文件、代码均以 BSD 协议发布。
谱表指谱号和五线谱合称,如图所示为高音谱表(上)和低音谱表(下)。
↩︎
相关文章:
强大的音乐乐谱控件库
2023 Conmajia, 2018 Ajcek84 SN: 23C.1 本中文翻译已获原作者首肯。 简介 PSAM 控件库——波兰音乐文档系统——是用于显示、排版乐谱的强大 WinForm 库,包含用于绘制乐谱的名为 IncipitViewer 控件,乐谱内容可以从 MusicXml 文件读取,或者…...
数据库——简单查询复杂查询
1.实验内容及原理 1. 在 Windows 系统中安装 VMWare 虚拟机,在 VMWare 中安装 Ubuntu 系统,并在 Ubuntu 中搭建 LAMP 实验环境。 2. 使用 MySQL 进行一些基本操作: (1)登录 MySQL,在 MySQL 中创建用户,…...
java虚拟机内存管理
文章目录 概要一、jdk7与jdk8内存结构的差异二、程序计数器三、虚拟机栈3.1 什么是虚拟机栈3.2 什么是栈帧3.3 栈帧的组成 四、本地方法栈五、堆5.1 堆的特点5.2 堆的结构5.3 堆的参数配置 六、方法区6.1 方法区结构6.2 运行时常量池 七、元空间 概要 根据 JVM 规范࿰…...
Hive实战:词频统计
文章目录 一、实战概述二、提出任务三、完成任务(一)准备数据文件1、在虚拟机上创建文本文件2、将文本文件上传到HDFS指定目录 (二)实现步骤1、启动Hive Metastore服务2、启动Hive客户端3、基于HDFS文件创建外部表4、查询单词表&a…...
FairyGUI-Cocos Creator官方Demo源码解读
博主在学习Cocos Creator的时候,发现了一款免费的UI编辑器FairyGUI。这款编辑器的能力十分强大,但是网上的学习资源比较少,坑比较多,主要学习方式就是阅读官方文档和练习官方Demo。这里博主进行官方Demo的解读。 从gitee上克隆项目…...
LabVIEW利用视觉引导机开发器人精准抓取
LabVIEW利用视觉引导机开发器人精准抓取 本项目利用单目视觉技术指导多关节机器人精确抓取三维物体的技术。通过改进传统的相机标定方法,结合LabVIEW平台的Vision Development和Vision Builder forAutomated Inspection组件,优化了摄像系统的标定过程&a…...
【Linux】指令(本人使用比较少的)——笔记(持续更新)
文章目录 ps -axj:查看进程ps -aL:查看线程echo $?:查看最近程序的退出码jobs:查看后台运行的线程组fd 任务号:将后台任务提到前台bg 任务号:将暂停的后台程序重启netstat -nltp:查看服务及监听…...
032 - STM32学习笔记 - TIM基本定时器(一) - 定时器基本知识
032 - STM32学习笔记 - TIM定时器(一) - 基本定时器知识 这节开始学习一下TIM定时器功能,从字面意思上理解,定时器的基本功能就是用来定时,与定时器相结合,可以实现一些周期性的数据发送、采集等功能&#…...
轮廓检测与处理
轮廓检测 先将图像转换成二值 gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度图 ret, thresh cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 变为二值,大于127置为255,小于100置为0.使用cv2.findContours(thresh, cv2.RETR_TREE, cv2.…...
跟着LearnOpenGL学习11--材质
文章目录 一、材质二、设置材质三、光的属性四、不同的光源颜色 一、材质 在现实世界里,每个物体会对光产生不同的反应。 比如,钢制物体看起来通常会比陶土花瓶更闪闪发光,一个木头箱子也不会与一个钢制箱子反射同样程度的光。 有些物体反…...
Java guava partition方法拆分集合自定义集合拆分方法
日常开发中,经常遇到拆分集合处理的场景,现在记录2中拆分集合的方法。 1. 使用Guava包提供的集合操作工具栏 Lists.partition()方法拆分 首先,引入maven依赖 <dependency><groupId>com.google.guava</groupId><artifa…...
GLTF编辑器-位移贴图实现破碎的路面
在线工具推荐: 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 位移贴图是一种可以用于增加模型细节和形状的贴图。它能够在渲染时针…...
多维时序 | MATLAB实现SSA-BiLSTM麻雀算法优化双向长短期记忆神经网络多变量时间序列预测
多维时序 | MATLAB实现SSA-BiLSTM麻雀算法优化双向长短期记忆神经网络多变量时间序列预测 目录 多维时序 | MATLAB实现SSA-BiLSTM麻雀算法优化双向长短期记忆神经网络多变量时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.MATLAB实现SSA-BiLSTM麻雀算法优化…...
docker安装Nacos和Rabbitmq
一、安装Nacos 首先需要拉取对应的镜像文件:(切换版本加上对应版本号即可,默认最新版) docker pull nacos/nacos-server 接着挂载目录: mkdir -p /mydata/nacos/logs/ #新建logs目录 mkdir -p …...
Android MVC 写法
前言 Model:负责数据逻辑 View:负责视图逻辑 Controller:负责业务逻辑 持有关系: 1、View 持有 Controller 2、Controller 持有 Model 3、Model 持有 View 辅助工具:ViewBinding 执行流程:View >…...
网络层解读
基本介绍 概述 当两台主机之间的距离较远(如相隔几十或几百公里,甚至几千公里)时,就需要另一种结构的网络,即广域网。广域网尚无严格的定义。通常是指覆盖范围很广(远超过一个城市的范围)的长距离的单个网络。它由一些结点交换机以及连接这些…...
js for和forEach 跳出循环 替代方案
1 for循环跳出 for(let i0;i<10;i){if(i5){break;}console.log(i) }在函数中也可以return跳出循环 function fn(){for(let i0;i<10;i){if(i5){return;}console.log(i)} } fn()for ... of效果同上 2 forEach循环跳出 break会报错 [1,2,3,4,5,6,7,8,9,10].forEach(i>…...
如何使用ArcGIS Pro自动矢量化建筑
相信你在使用ArcGIS Pro的时候已经发现了一个问题,那就是ArcGIS Pro没有ArcScan,在ArcGIS Pro中,Esri确实已经移除了ArcScan,没有了ArcScan我们如何自动矢量化地图,从地图中提取建筑等要素呢,这里为大家介绍…...
交互式笔记Jupyter Notebook本地部署并实现公网远程访问内网服务器
最近,我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念,而且内容风趣幽默。我觉得它对大家可能会有所帮助,所以我在此分享。点击这里跳转到网站。 文章目录 1.前言2.Jupyter Notebook的安装2.1 Jupyter Notebook下…...
41.坑王驾到第七期:uniapp开发微信小程序引用组件时报错!
一、错误再现 页面login引用了一个组件register,运行至小程序开发工具报错。 xxx.js 已被代码依赖分析忽略,无法被其他模块引用。 二、解决办法 在微信小程序的配置文件中找到setting节点,增加两个配置项。 “ignoreDevUnusedFiles”: fa…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]
报错信息:libc.so.6: cannot open shared object file: No such file or directory: #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...
FFmpeg avformat_open_input函数分析
函数内部的总体流程如下: avformat_open_input 精简后的代码如下: int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...
