news 2026/10/16 13:27:37

Alda 音符语法完全指南:八度、时值、临时变音记号与调号实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Alda 音符语法完全指南:八度、时值、临时变音记号与调号实战
  • 编程语言
  • 音频
  • CLI

【免费下载链接】alda

A music programming language for musicians. :notes:

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

本篇技术指南围绕 Alda 音乐编程语言的核心基础——音符(Notes)展开,系统讲解音符的三大组成要素:八度组、时值与音名/变音记号,并深入介绍 Alda 独有的高级节奏能力(非标准音符时值、十进制时值、毫秒/秒时长)。读完本篇,你将掌握用 Alda 编写可运行乐谱的基本功,能够独立写出从单音符到带调号的完整音阶与旋律片段,并理解其底层解析与事件生成原理。本文对应仓库中的官方文档 doc/doc_zh_cn/notes_zh_cn.md。

音符语法总览

Alda 的音符语法深受 MML(Music Macro Language) 启发。一个音符由以下部分组成:

  • 从a到g的一个音名(必选);
  • 任意数量的临时变音记号(可选);
  • 一个音符时值标记(可选)。

即:

音名 [变音记号] [时值标记]

例如c表示默认八度、默认时值的 C 音,c+4表示升 C 的四分音符。在扫描器层面,c会被识别为NoteLettertoken,+为Sharp,-为Flat,_为Natural,数字时值则生成NoteLength/NoteLengthMs/NoteLengthSecondstoken,具体实现见 client/parser/scanner.go。

八度组(Octave)

西方音乐理论将音高划分为每 12 个音一组(十二平均律)的重复八度组,例如升序的c c# d d# e f f# g g# a a# b(再往上是高八度的c c# d ...)。音名(如 C#)与八度的组合决定了音符的频率(Hz)。八度组用数字表示,通常在 1 到 7 之间,对应科学音高记号(也称国际音高记号)。例如中央 C 与 A440 都位于第 4 个八度组——这也是 Alda 的默认八度组。

与 MML 一样,八度组与音符本身是分开设置的:八度不是"附加"在音符上的,而是每个音符在解析时查看当前的八度组来确定自己的音高。

设置八度组有两种方式:

语法含义
o5将八度组设置为 5(任何整数都可以跟在o后面)
<将当前八度组减少 1
>将当前八度组增加 1

o指令、<与>在扫描器中分别对应OctaveSet、OctaveDown、OctaveUp三种 token(见 client/parser/scanner.go),并最终转化为模型层OctaveSet/OctaveUp/OctaveDown这类属性更新(AttributeUpdate,见 client/model/attributes.go)。解析器的测试用例 client/parser/octaves_test.go 验证了包括>>>(连续上移三个八度)、><>(上移→下移→上移)、以及>c、c>这类"八度指令紧跟音符/音符紧跟八度指令"在内的各种写法。

音符时值(Duration)

在 Alda 中,音符时值通常以标准音乐符号中的音符长度表示,采用数字形式:4是四分音符,2是二分音符,1是全音符,以此类推。

附点(Dots)

音符后面可以添加任意数量的点.,其作用与标准音乐符号中的附点一致——将音符的时值延长到其原值的 1.5 倍(即延长其一半的时值)。后续每加一个点,延长的时值都是上一个点所延长时值的一半:

写法含义拍数
2二分音符2 拍
2.附点二分音符3 拍(2 × 1.5)
2..复附点二分音符3.5 拍(2 × 1.5 + 2 × 0.5 × 0.5)

模型层通过NoteLength{Denominator, Dots}表达这一概念,拍数计算公式为(4 / Denominator) * (2 - 2^(-Dots)),见 client/model/duration.go 与Beats()实现(client/model/duration.go)。单元测试 client/model/duration_test.go 验证了这些换算:四分音符 = 1 拍、附点四分音符 = 1.5 拍、全音符 = 4 拍、附点全音符 = 6 拍、复附点全音符 = 7 拍。

连音线(Tie)

音符时值也可以用连音线语法~相加,例如4~4表示两个四分音符连在一起,总共 2 拍。在扫描器中~生成Tietoken(见 client/parser/scanner.go),在模型层,Duration由若干DurationComponent相加得到,Beats()与Ms()都会把所有组件求和(见 client/model/duration.go)。

默认时值的"粘性"跟踪

当音符在乐谱中按顺序解析时,Alda 会持续跟踪当前八度组和当前默认音符时值。每当指定新的八度组或音符时值,那些数据就成为新的默认值;后续未显式写明时值的音符,都会沿用这一默认时值。

在每个乐器部分的开头,默认八度组为4,默认音符时值为4(即四分音符,1 拍)。源码层面,"时值粘性"由 client/model/note.go 中的effectiveDuration与updateDefaultDuration实现:若音符未指定时值,则使用该乐器部分当前默认的part.Duration;若指定了时值,则该时值同时被写回为部分的新默认值。这意味着你可以在乐谱中先写一个c4,后面的d e f都会自动按四分音符演奏,直到下一个显式时值出现。

高级节奏(Advanced Rhythms)

Alda 在节奏表达上有几个超越传统记谱的独特能力:

1. 非标准数字时值。你可以使用非 2 的幂的数字作为音符时值标记。例如6表示在 4/4 拍中持续 1/6 小节的音符。在标准记谱中没有"六分音符"这种东西,这种时值通常会被记作四分音符三连音中的一个音符;但在 Alda 中,"六分音符"不一定是三连音的一部分,这为创造更多有趣的节奏提供了可能性。

2. 非整数(十进制)音符时值。扩展到上述概念,Alda 允许小数音符时值:例如c0.5(西方古典记谱中的双全音符)的时值是c1(全音符)的两倍。这些数字不必是 2 的幂,例如c2.4同样是合法的。扫描器的parseNoteLength会先消费整数部分,若遇到小数点后跟数字则继续消费小数部分,最终把整个数值作为denominator解析(见 client/parser/scanner.go)。

3. Cram 表达式。Alda 还提供了一种指定节奏的替代方法——cram 表达式,用于在一段时间内塞入指定数量的音符。

4. 毫秒与秒。音符时值还可以用毫秒(ms)和秒(s)表示,并且可以随意与标准音符长度混搭:

c350ms # 持续350毫秒的C音符 d2s # 持续2秒的D音符 e2s~200ms # 持续2秒+200毫秒的E音符 f300ms~4. # 持续300毫秒+附点四分音符的F音符

扫描器在数字后遇到s且其后是合法分隔符时生成NoteLengthSecondstoken,遇到ms时生成NoteLengthMstoken(见 client/parser/scanner.go)。模型层对应NoteLengthMs与NoteLengthSeconds两种时值组件:毫秒组件直接返回自身毫秒数,秒组件乘以 1000 转换为毫秒(见 client/model/duration.go)。注意这两种组件无法直接换算为"拍数"(Beats()会直接 panic,见 client/model/duration.go),但它们可以自由地与标准音符时值通过~组合成同一个Duration。

音符格式与临时变音记号

一个音符的完整格式为:从a到g的一个字母 + 任意数量的临时变音记号(可选)+ 音符时值标记(可选)。

降号和升号分别使音高降低/升高半音。在 Alda 中,降号表示为-,升号表示为+。你可以使用多个升号或降号,甚至把它们组合起来使用,例如:

  • c+= 升 C
  • c++= 双升号 C = D
  • b-= 降 B

解析器测试 client/parser/notes_test.go 中包含了c+(升音)、b-(降音)、c++(双升音)、b--(双降音)等用例,验证了任意数量变音记号的累积效果。在模型层,LetterAndAccidentals保存音名与变音记号列表,CalculateMidiNote会将每个升号 +1、每个降号 -1 得到最终的 MIDI 音高(见 client/model/pitch.go)。

用调号代替逐个升降号

对于非 C 大调的乐曲,如果每个不在调内的音都需要写升/降号,重复书写会非常繁琐。此时更推荐使用调号,为每个需要的音名预设升/降号以匹配调性,乐谱会按定义的升降号自动演奏。下文示例中演示了具体用法。

用临时变音记号覆盖调号

要覆盖调号预设的降号/升号,可以添加临时变音记号:+/-使音符临时升调/降调;_代表还原号,强制音符为自然音。例如c_是 C 自然音,无论调号预设中给 C 音名设置了什么升降号。这对应扫描器中的Naturaltoken 与模型层Accidental枚举中的Natural(见 client/model/pitch.go)。

完整示例:B 大调音阶

以下是 1 个八度的 B 大调音阶,从第 4 个八度组开始先上行后下行:

o4 b4 > c+8 d+ e f+ g+ a+ b4 a+8 g+ f+ e d+ c+ < b2.

第二个示例在开头处预设了 B 大调中被升高的那些音名(f+ c+ g+ d+ a+),这样乐谱中就不必重复书写升降号,音符会自动以预设的升降号演奏:

(key-signature "f+ c+ g+ d+ a+") o4 b4 > c8 d e f g a b4 a8 g f e d c < b2.

仓库示例 examples/key_signature.alda 展示了更完整的调号实战:先用字符串形式设置(key-signature "f+ c+ g+"),再用c_、f_、g_还原号覆盖个别音,随后切换到'(g minor)小调调号,最后使用列表形式'(e (flat) b (flat))指定降号。调号相关属性的完整说明(值类型、缩写key-sig、支持的调式等)见 doc/doc_zh_cn/attributes_zh_cn.md。

源码层面的实现原理

扫描与解析

从源码结构看,Alda 的音符解析分为两个阶段:扫描器 client/parser/scanner.go 先将源码文本切分为 token(NoteLetter、Sharp、Flat、Natural、NoteLength、OctaveSet、OctaveUp、OctaveDown、Tie等),再由语法解析器组合成 AST 更新(见 client/parser/parser.go)。isNoteLetter限定只有a到g是合法的音符字母(client/parser/scanner.go),followsNoteLetter决定一个字母后可以跟随什么字符(数字、变音记号、~连音线、</>八度移动等),从而避免歧义(client/parser/scanner.go)。

时值如何变成真实时长

在模型层,每个音符最终会被转换为带绝对时间信息的NoteEvent(MIDI 音符号、偏移、时长、可听时长、音量、声像等),见 client/model/note.go。Note.UpdateScore会为每个当前乐器部分计算时长:标准音符时值依据Beats()换算拍数,再结合part.Tempo得到毫秒数(60000 / tempo为每拍毫秒数,见 client/model/duration.go);未连音(非 slur)的音符还会乘以part.Quantization得到"可听时长"。这些换算关系可以在 client/model/duration_test.go 的测试用例中看到——例如附点音符、全音符到拍数/毫秒的转换都有一一对应的断言。

变音记号与 MIDI 音高

LetterAndAccidentals.CalculateMidiNote展示了完整求音高流程:先按(octave + 1) * 12 + 音名音程计算基准 MIDI 音符号,若音符未显式给出变音记号则取调号keySignature[NoteLetter]中的默认升降号,否则使用音符自带的变音记号列表逐项加减,最后叠加乐器移调(见 client/model/pitch.go)。这也印证了文档中"临时变音记号覆盖调号"的行为:只要音符自带+/-/_,调号即被忽略。


至此,你已经掌握了 Alda 音符语法的全部核心内容:八度组(o/</>)、标准与附点/连音时值、高级节奏(非标准数字、小数、ms/s)、变音记号与调号的配合使用。建议结合仓库中的 examples/key_signature.alda、examples/dynamics.alda 等示例,以及 cram 表达式、属性 文档继续深入,配合alda play命令(见 client/cmd/play.go)实际聆听效果,逐步构建完整的 Alda 作曲工作流。

  • 编程语言
  • 音频
  • CLI

【免费下载链接】alda

A music programming language for musicians. :notes:

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

相关推荐

上一篇:QuantStats技术解构:量化投资分析效率提升的四个实践维度
下一篇:FullCalendar 版本演进全解析:从 v1 到 v7 的架构变革、破坏性变更与升级要点

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/17 1:02:09

如何用ArtCraft Omni API批量生成?batch与all_job_tokens的实战技巧

如何用ArtCraft Omni API批量生成&#xff1f;batch与all_job_tokens的实战技巧 【免费下载链接】artcraft ArtCraft is an intentional crafting engine for artists, designers, and filmmakers 项目地址: https://gitcode.com/GitHub_Trending/ar/artcraft ArtCraft …

作者头像 李华
网站建设 2026/10/14 10:26:01

瑞侃170233-1与170265-1端子区别详解及采购避坑指南

前两天还有做采购的同行发消息来问我&#xff1a;仓库里翻出两包瑞侃料&#xff0c;一包写着170233-1&#xff0c;另一包写着170265-1&#xff0c;编码就差两个数字&#xff0c;供应商报出来的价格却差了不少&#xff0c;你帮我看看是不是同一种东西。这个问题听着小&#xff0…

作者头像 李华
网站建设 2026/10/16 9:48:20

SEIR+LSTM 传染病预测实战:Python 源码与避坑指南

简介&#xff1a;本资源面向计算机、人工智能、数据科学等专业的在校学生与教师&#xff0c;提供基于SEIR传染病动力学模型与LSTM神经网络实现新型冠状病毒肺炎预测的完整Python项目&#xff0c;可作为课程设计、期末大作业或毕业设计的参考方案。压缩包共31个文件&#xff0c;…

作者头像 李华
网站建设 2026/10/16 0:22:45

Voyager 生态系统指南:受 Voyager 启发的跨平台 AI 增强扩展全景

AI 应用前端插件系统提示工程 【免费下载链接】voyager Enhancement suite for Gemini, AI Studio, Claude, ChatGPT & DeepSeek — plus a prompt manager for any website, DeepSeek Harness included. / 面向 Gemini、AI Studio、Claude、ChatGPT 与 DeepSeek 的增强套件…

作者头像 李华