Skip to content

Commit f29d966

Browse files
committed
feat(data): 增强 ABC 解析器以支持时间单位配置和元数据冗余存储
- 在 SNMusicProps 中新增 timeUnit 属性,用于统一音符、休止符、歌词等在时间序列上的位置对齐 - 引入 SNTimeUnit 接口,定义基本时间单位和每拍的时值 - 更新 SNSectionMeta 接口,支持冗余存储的通用信息(如标题、创作者)和 ABC 特有字段 - 在 AbcParser 中实现 noteLength 到 SNTimeUnit 的转换,确保布局计算的准确性 - 改进 parseSectionHeader 方法,支持从 ABC 格式提取并存储时间单位信息 该变更提升了 ABC 解析器的灵活性和兼容性,为多记谱法支持奠定基础。
1 parent 45c6c3b commit f29d966

6 files changed

Lines changed: 369 additions & 15 deletions

File tree

packages/simple-notation/src/core/model/base.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ export interface SNPitch {
3939
accidental: SNAccidental;
4040
}
4141

42+
/**
43+
* 持续时间(以基本时间单位为单位的数值)
44+
* 例如:如果 baseTimeUnit = 1/32,则:
45+
* - 全音符 = 32 个单位
46+
* - 四分音符 = 8 个单位
47+
* - 八分音符 = 4 个单位
48+
*/
4249
export type SNDuration = number;
4350

4451
export enum SNAccidental {
@@ -49,6 +56,32 @@ export enum SNAccidental {
4956
DOUBLE_FLAT = 'doubleFlat',
5057
}
5158

59+
/**
60+
* 时间单位配置
61+
* 用于定义基本时间单位,统一不同记谱法的时间对齐计算
62+
*/
63+
export interface SNTimeUnit {
64+
/**
65+
* 基本时间单位(相对于全音符的比例)
66+
* 例如:
67+
* - 1/32: 将全音符分为 32 个单位,最小精度为三十二分音符
68+
* - 1/64: 将全音符分为 64 个单位,最小精度为六十四分音符
69+
* - 1/96: 将全音符分为 96 个单位(支持三连音的精确对齐)
70+
*
71+
* 所有音符、休止符、歌词等的 duration 都用这个单位表示
72+
*/
73+
baseUnit: number; // 例如:1/32, 1/64, 1/96
74+
75+
/**
76+
* 每拍的时值(相对于全音符的比例)
77+
* 由拍号的 denominator 决定,用于将时间单位转换为拍数
78+
* 例如:
79+
* - 4/4 拍:beatUnit = 1/4(一拍是四分音符)
80+
* - 3/8 拍:beatUnit = 1/8(一拍是八分音符)
81+
*/
82+
beatUnit?: number; // 自动根据 timeSignature 计算,也可以手动设置
83+
}
84+
5285
/**
5386
* 音乐属性(所有层级都可能有的,参与布局渲染)
5487
* score、section、measure 等层级都可能有这些属性
@@ -57,6 +90,11 @@ export interface SNMusicProps {
5790
timeSignature?: SNTimeSignature; // 拍号(如 4/4)
5891
keySignature?: SNKeySignature; // 调号(如 C大调)
5992
tempo?: SNTempo; // 速度(如 120 BPM)
93+
/**
94+
* 时间单位配置(通用方案)
95+
* 用于确定最小时间单位,计算音符、休止符、歌词等在时间序列上的位置对齐
96+
*/
97+
timeUnit?: SNTimeUnit;
6098
}
6199

62100
/**

packages/simple-notation/src/data/model/abc.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ export interface SNRootMeta {
2626
* - meta 中:数据层追溯来源,知道这些字段来自 ABC 的 T:、C: 等字段
2727
*
2828
* 2. ABC 特有的元数据仅存储在 meta 中(不参与布局渲染):
29-
* - origin, area, notes, copyright, noteLength 等
29+
* - origin, area, notes, copyright 等
30+
* - noteLength(冗余存储,用于追溯 ABC 来源,同时在 props 中用于布局计算)
3031
*
3132
* 根据 ABC 标准 v2.1
3233
* @see https://abcnotation.com/wiki/abc:standard:v2.1
@@ -47,8 +48,38 @@ export interface SNScoreMeta {
4748
notes?: string;
4849
/** 版权信息(S: 字段在头部时)- ABC 特有 */
4950
copyright?: string;
50-
/** 默认音符长度(L: 字段,如 "1/4", "1/8")- ABC 特有 */
51+
/** 默认音符长度(L: 字段,如 "1/4", "1/8")- ABC 特有,存储在 meta 中以便追溯来源,已转换为 timeUnit 存储在 props 中 */
5152
noteLength?: string;
5253
/** 其他 ABC 特有的字段(H:, G:, R:, Z:, D:, F:, B: 等) */
5354
[key: string]: unknown;
5455
}
56+
57+
/**
58+
* Section 级别的元数据(ABC 特有的 section 元数据)
59+
*
60+
* 设计理念:支持冗余存储(与 Score 层一致)
61+
* 1. 通用布局渲染信息(title, subtitle, contributors)同时存储在:
62+
* - props 中:布局层统一访问,不关心具体记谱法格式
63+
* - meta 中:数据层追溯来源,知道这些字段来自 ABC 的 T:、C: 等字段
64+
*
65+
* 2. ABC 特有的元数据仅存储在 meta 中(不参与布局渲染):
66+
* - 其他 ABC 特有字段
67+
*
68+
* 根据 ABC 标准 v2.1,Section 可以有自己的标题、拍号、调号、速度等
69+
* @see https://abcnotation.com/wiki/abc:standard:v2.1
70+
*/
71+
export interface SNSectionMeta {
72+
/** 标题(T: 字段)- ABC 特有,冗余存储在 meta 中以便追溯来源 */
73+
title?: string;
74+
/** 副标题(第二个 T: 字段)- ABC 特有,冗余存储在 meta 中以便追溯来源 */
75+
subtitle?: string;
76+
/** 创作者列表(C: 字段)- ABC 特有,冗余存储在 meta 中以便追溯来源 */
77+
contributors?: Array<{ name: string; role?: string }>;
78+
79+
/** 默认音符长度(L: 字段,如 "1/4", "1/8")- ABC 特有 */
80+
noteLength?: string;
81+
/** Section 标识符(S: 字段的值)- ABC 特有 */
82+
sectionId?: string;
83+
/** 其他 ABC 特有的字段 */
84+
[key: string]: unknown;
85+
}

packages/simple-notation/src/data/node/measure.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { SNParserNode } from '@data/node';
99
* - timeSignature(拍号,小节内可能有变化)
1010
* - keySignature(调号,小节内可能有转调)
1111
* - tempo(速度,小节内可能有速度变化)
12+
* - timeUnit(时间单位配置,通用方案,用于确定音符、休止符、歌词等在时间序列上的位置对齐)
1213
*
1314
* 注意:Measure 只使用 SNMusicProps(不包含 title, subtitle, contributors),
1415
* 因为这些元信息只在 score/section 层级存在

packages/simple-notation/src/data/node/score.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type { SNScoreMeta } from '@data/model/abc';
1010
* - timeSignature(拍号)
1111
* - keySignature(调号)
1212
* - tempo(速度)
13+
* - timeUnit(时间单位配置,通用方案,用于确定音符、休止符、歌词等在时间序列上的位置对齐)
1314
* - 元信息属性(只在 score/section 层级有):
1415
* - title, subtitle(标题、副标题)
1516
* - contributors(创作者信息)
@@ -21,7 +22,7 @@ import type { SNScoreMeta } from '@data/model/abc';
2122
* - origin, area(来源、地区)
2223
* - notes(注释)
2324
* - copyright(版权)
24-
* - noteLength(默认音符长度
25+
* - noteLength(ABC 特有的 L: 字段,冗余存储在 meta 中以便追溯来源,已转换为 timeUnit 存储在 props 中
2526
* - 其他 ABC 特有字段
2627
*
2728
* 设计理念:

packages/simple-notation/src/data/node/section.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,35 @@
1-
import { SNParserMeta } from '@data/model';
21
import { SNParserNode } from '@data/node';
2+
import type { SNSectionMeta } from '@data/model/abc';
33

44
/**
55
* Section(篇章)节点
66
*
7-
* 数据分类:
7+
* 数据分类(支持冗余存储)
88
* 1. 通用布局渲染信息 → 存放在 props 中(类型:SNScoreProps)
9-
* - 音乐属性(timeSignature, keySignature, tempo)
10-
* - 元信息属性(title, subtitle, contributors)
9+
* - 音乐属性(所有层级都可能有):
10+
* - timeSignature(拍号)
11+
* - keySignature(调号)
12+
* - tempo(速度)
13+
* - timeUnit(时间单位配置,通用方案,用于确定音符、休止符、歌词等在时间序列上的位置对齐)
14+
* - 元信息属性(只在 score/section 层级有):
15+
* - title, subtitle(标题、副标题)
16+
* - contributors(创作者信息)
1117
*
12-
* 2. ABC 特有的元数据 → 存放在 meta 中
18+
* 2. ABC 特有的元数据 → 存放在 meta 中(类型:SNSectionMeta)
19+
* - 冗余存储的通用信息(同时也在 props 中):
20+
* - title, subtitle, contributors(用于追溯 ABC 来源)
21+
* - ABC 特有的元数据(仅存在 meta 中):
22+
* - noteLength(默认音符长度)
23+
* - sectionId(S: 字段的值)
24+
* - 其他 ABC 特有字段
25+
*
26+
* 设计理念:
27+
* - props:布局层统一访问,不关心具体记谱法格式
28+
* - meta:数据层追溯来源,知道字段来自 ABC 的哪个字段(T:, M:, K: 等)
1329
*
1430
* 注意:Section 可以有自己的标题和音乐属性(如转调),继承或覆盖 Score 的设置
1531
*/
16-
export class SNParserSection extends SNParserNode<SNParserMeta> {
32+
export class SNParserSection extends SNParserNode<SNSectionMeta> {
1733
constructor({ id, originStr }: Pick<SNParserNode, 'id' | 'originStr'>) {
1834
super({ id, originStr, type: 'section' });
1935
}

0 commit comments

Comments
 (0)