UNPKG

simple-notation

Version:

A dynamic Jianpu (numbered musical notation) rendering library. Generate beautiful music scores on your web pages from text. Designed for the modern web.

1,763 lines (1,701 loc) 70.6 kB
import { SNStaveOptions as SNStaveOptions_2 } from './types'; /** * ABC解析器实现,功能与模板解析器一致,但独立实现 */ export declare class AbcParser extends BaseParser { private info; private L; /** 当前处理的文本位置 */ private currentPosition; /** 当前乐句的起始位置 */ private currentStaveStartPos; /** 当前小节的起始位置 */ private currentMeasureStartPos; /** 原始文本数据 */ private originalText; /** * 解析ABC乐谱字符串,仅支持模板语法中存在的功能 * @param abcScore - ABC乐谱字符串 * @returns 解析后的乐谱数据对象 */ parse(data: SNData): { parsedScore: SNStaveOptions[]; info?: SNDataInfo; lyric?: string; score?: string; }; /** * 解析单个音符的数据 * @param noteData - 音符的原始字符串数据 * @returns 解析后的音符信息对象 */ parseNote(noteData: string): SNNoteOptions; /** * 解析单个小节的数据 * @param measureData - 小节的原始字符串数据 * @param noteCount - 当前已处理的音符总数 * @param expectedBeats - 当前小节应有的拍数(用于时值校验) * @returns 解析后的小节信息对象 */ parseMeasure(measureData: string, noteCount: number, expectedBeats: number): { weight: number; measureNoteCount: number; noteOptions: SNNoteOptions[]; }; /** * 解析单个乐句中的小节数据并添加到五线谱选项中 * @param stave - 单个乐句的原始字符串数据 * @param noteCount - 当前已处理的音符总数 * @param measureCount - 当前已处理的小节总数 * @param expectedBeats - 当前小节应有的拍数(用于时值校验) * @returns 解析后的小节信息和更新后的音符、小节总数 */ parseStave(stave: string, noteCount: number, measureCount: number, expectedBeats: number): { staveOption: SNStaveOptions; noteCount: number; measureCount: number; }; /** * 解析完整的谱面数据 * @param scoreData - 谱面的原始字符串数据 * @returns 解析后的五线谱选项数组 */ parseScore(scoreData: string): SNStaveOptions[]; } /** * 抽象解析器基类,定义乐谱解析的核心方法接口 * @abstract */ export declare abstract class BaseParser { /** * 解析入口方法,具体实现由子类定义 * @param data - 原始乐谱数据 * @returns 最终解析后的乐谱数据 */ abstract parse(data: SNData): { parsedScore: SNStaveOptions[]; info?: SNDataInfo; lyric?: string; score?: string; }; /** * 解析单个音符的数据 * @param noteData - 音符的原始字符串数据 * @returns 解析后的音符信息对象 */ abstract parseNote(noteData: string): SNNoteOptions; /** * 解析单个小节的数据 * @param measureData - 小节的原始字符串数据 * @param noteCount - 当前已处理的音符总数 * @param expectedBeats - 当前小节应有的拍数(用于时值校验) * @returns 解析后的小节信息对象 */ abstract parseMeasure(measureData: string, noteCount: number, expectedBeats: number): { weight: number; measureNoteCount: number; noteOptions: SNNoteOptions[]; }; /** * 解析单个乐句中的小节数据并添加到五线谱选项中 * @param stave - 单个乐句的原始字符串数据 * @param noteCount - 当前已处理的音符总数 * @param measureCount - 当前已处理的小节总数 * @param expectedBeats - 当前小节应有的拍数(用于时值校验) * @param staveStartPos - 当前乐句的起始位置 * @returns 解析后的小节信息和更新后的音符、小节总数 */ abstract parseStave(stave: string, noteCount: number, measureCount: number, expectedBeats: number, staveStartPos: number): { staveOption: SNStaveOptions; noteCount: number; measureCount: number; }; /** * 解析完整的谱面数据 * @param scoreData - 谱面的原始字符串数据 * @returns 解析后的五线谱选项数组 */ abstract parseScore(scoreData: string): SNStaveOptions[]; } /** * Bravura 字体音乐符号实现 * @class BravuraMusicSymbols */ export declare class BravuraMusicSymbols { /** * Bravura 符号映射表 */ static readonly SYMBOLS: { SHARP: string; DOUBLE_SHARP: string; FLAT: string; DOUBLE_FLAT: string; NaTURAL: string; FLAG_1: string; FLAG_2: string; REST_WHOLE: string; REST_HALF: string; REST_QUARTER: string; REST_EIGHTH: string; REST_SIXTEENTH: string; REST_32ND: string; }; /** * 获取符号的字符串 * @param symbolKey */ static getSymbol(symbolKey: SNBravuraMusicSymbol): string; /** * 创建 Bravura 字体音乐符号 SVG tspan 元素 * @param symbolKey * @param options */ static createSymbol(symbolKey: SNBravuraMusicSymbol, options: SNMusicSymbolOptions): SVGTextElement; } export declare class ChordTool { static pianoChordMap: Record<string, string[]>; static guitarChordPositionsMap: Record<string, (number | null)[]>; /** * 吉他调弦的音高 (MIDI值)。从粗到细,6弦到1弦。 * E2 A2 D3 G3 B3 E4 */ guitarTuningMidis: Record<number, number>; /** * 将和弦符号转换为对应的钢琴音高字符串数组。 * @param chordSymbol 和弦符号 (例如 'C', 'Am', 'G7', '1', '2m') * @returns 对应的音高字符串数组 (例如 ['C3', 'E3', 'G3']),如果找不到则返回空数组。 */ static getPianoNotesForChord(chordSymbol: string): string[]; /** * 将和弦符号转换为对应的吉他指板位置数组。 * @param chordSymbol 和弦符号 * @returns 对应的吉他指板位置数组 [{ string: number, fret: number | null }],如果找不到则返回空数组。 */ static getGuitarPositionsForChord(chordSymbol: string): (number | null)[]; /** * 根据吉他指板位置获取对应的音高(MIDI值)。 * @param string 弦号 (1-6) * @param fret 品位 * @returns 音高 MIDI 值,如果弦号或品位无效则返回 null。 */ static getMidiForGuitarPosition(string: number, fret: number): number | null; /** * 根据吉他指板位置获取对应的音名(带八度)。 * @param string 弦号 (1-6) * @param fret 品位 * @returns 音名字符串 (例如 'C3'),如果弦号或品位无效则返回 null。 */ static getNoteNameForGuitarPosition(string: number, fret: number): string | null; } /** * 事件回调函数类型 */ export declare type EventCallback = (event: CustomEvent) => void; declare type EventCallback_2 = (event: CustomEvent) => void; /** * 事件详情类型 */ export declare type EventDetail = { e: Event; }; /** * 表示吉他指板上的特定位置。 */ export declare interface GuitarPosition { string: number; fret: number; } export declare class Logger { /** * 调试模式开关,默认为 false */ static isDebugMode: boolean; /** * 输出信息日志 * @param message - 要输出的信息 * @param context - 信息的上下文,用于语义化标识问题位置 */ static info(message: string, context?: string): void; /** * 输出警告日志 * @param message - 要输出的警告信息 * @param context - 警告的上下文,用于语义化标识问题位置 */ static warn(message: string, context?: string): void; /** * 输出错误日志 * @param message - 要输出的错误信息 * @param context - 错误的上下文,用于语义化标识问题位置 * * 格式应该如下所示: * [ERROR] [context] message * [ERROR] message * * context一般为: * 1. 文件名 * 2. 函数名 * * message一般为: * 1. 错误信息 * 2. 错误堆栈 */ static error(message: string, context?: string): void; /** * 输出调试日志 * @param message - 要输出的调试信息 * @param context - 调试信息的上下文,用于语义化标识问题位置 */ static debug(message: string, context?: string): void; } /** * SimpleNotation 类 - 简谱渲染的主类 * * @class SimpleNotation * @description * 这个类负责创建和管理简谱的渲染。它处理SVG元素的创建、 * 数据的加载和渲染、以及视图的大小调整等核心功能。 * * @example * ```typescript * const container = document.querySelector('#container'); * const sn = new SimpleNotation(container, { * width: 800, * height: 600 * }); * * // 订阅音符点击事件 * sn.on('note:click', (event) => { * console.log('点击了音符:', event.detail.noteTag); * }); * ``` */ export declare class SimpleNotation extends SNBox { container: HTMLDivElement; /** SVG根节点 */ el: SVGElement; /** 内容渲染组件 */ content: SNContent | null; /** ResizeObserver实例 */ private resizeObserver?; /** 事件系统实例 */ private eventSystem; /** * 创建一个新的简谱实例 * * @param container - 用于承载简谱的 DOM 容器元素 * @param options - 可选的配置项,包括宽度、高度等 * @throws {Error} 当容器元素为空时抛出错误 */ constructor(container: HTMLDivElement, options?: SNOptions); /** * 订阅事件 * @param event 事件名称 * @param callback 回调函数 * @returns {SimpleNotation} 返回this以支持链式调用 */ on(event: string, callback: EventCallback_2): SimpleNotation; /** * 取消订阅事件 * @param event 事件名称 * @param callback 回调函数 * @returns {SimpleNotation} 返回this以支持链式调用 */ off(event: string, callback: EventCallback_2): SimpleNotation; /** * 销毁SimpleNotation实例,释放资源 */ destroy(): void; /** * 更新配置项并重新渲染 * * @param options - 新的配置项 * @description * 这个方法会更新配置项并重新绘制简谱。它会: * 1. 更新运行时配置 * 2. 重新创建内容组件 * 3. 绘制信息区域 * 4. 绘制谱面内容 */ updateOptions(options: SNOptions): void; resetOptions(options?: SNOptions): void; /** * 加载简谱数据并重新渲染 * * @param data - 简谱数据,包含谱面信息和音符数据 * @param type - 数据类型,默认为模板写法(template),可选abc写法 */ loadData(data: SNData, type?: SNDataType): void; render(): void; /** * 调整简谱视图的大小 * * @param width - 新的宽度(像素) * @param height - 新的高度(像素) * @description * 这个方法会重新设置简谱的显示大小并重绘内容。它会: * 1. 更新配置中的尺寸 * 2. 更新 SVG 元素的尺寸 * 3. 重新创建并绘制内容 */ resize(width?: number, height?: number): void; /** * 获取解析后的乐谱结构 * @returns {SNStaveOptions[]} */ getParsedScore(): SNStaveOptions_2[]; } export declare type SNAbcKey = 'C' | 'D' | 'E' | 'F' | 'G' | 'A' | 'B' | 'Cmin' | 'Dmin' | 'Emin' | 'Fmin' | 'Gmin' | 'Amin' | 'Bmin'; export declare class SNBeamLayer { private static el; constructor(scoreEl: SVGGElement); /** * 绘制所有 measure 的符杠 */ static draw(measures: SNMeasure[]): void; /** * 简谱下划线/beam分组绘制(乐谱标准分组) */ static drawSimpleUnderlines(measures: SNMeasure[]): void; /** * 吉他谱符杠分组绘制(乐谱标准分组) */ static drawGuitarBeams(measures: SNMeasure[]): void; /** * 绘制一组简谱下划线 */ static drawUnderlineGroup(group: SNNote[], underlineCount: number): void; /** * 绘制一组吉他谱符杠 */ static drawGuitarBeamGroup(group: SNNote[], underlineCount: number): void; } /** * 边框盒子调试配置。 * @property {boolean} [inner] - 是否显示内边框。 * @property {boolean} [outer] - 是否显示外边框。 * @property {string} [innerColor] - 内边框颜色。 * @property {number} [innerLineWidth] - 内边框线宽。 * @property {string} [outerColor] - 外边框颜色。 * @property {number} [outerLineWidth] - 外边框线宽。 */ export declare interface SNBorderBoxOptions { inner?: boolean; outer?: boolean; innerColor?: string; innerLineWidth?: number; outerColor?: string; outerLineWidth?: number; } export declare class SNBorderLayer { /** SVG group 元素,作为内容的容器 */ static el: SVGGElement; static borderMap: Map<string, SVGRectElement>; constructor(svg: SVGElement); static addBorderBox(borderType: string, el: SVGRectElement): void; static destroyed(): void; } export declare class SNBox { parent: SNBox | null; type: SNBoxType; x: number; y: number; width: number; height: number; innerX: number; innerY: number; innerWidth: number; innerHeight: number; paddingX: number; paddingY: number; constructor(parent: SNBox | null, type: SNBoxType, x: number, y: number, width: number, height: number, padding?: number | number[]); resize(width: number, height: number): void; setWidth(width: number): void; setHeight(height: number, hasPadding?: boolean): void; getSNPointByLayer(boxType: SNBoxType): SNPoint; drawBorderBox(boxType: SNBoxType, options?: SNBorderBoxOptions, index?: number): void; drawOuterBox(options: SNBorderBoxOptions): SVGRectElement; drawInnerBox(options: SNBorderBoxOptions): SVGRectElement; drawBox(x: number, y: number, width: number, height: number, color: string, lineWidth: number): SVGRectElement; } /** * 简谱渲染中的盒子类型枚举。 * @enum {string} */ export declare enum SNBoxType { /** 根节点 */ ROOT = "root", /** 内容区域 */ CONTENT = "content", /** 信息区域 */ INFO = "info", /** 总谱区域 */ SCORE = "score", /** 乐句区域 */ STAVE = "stave", /** 小节区域 */ MEASURE = "measure", /** 音符区域 */ NOTE = "note" } export declare type SNBravuraMusicSymbol = 'SHARP' | 'DOUBLE_SHARP' | 'FLAT' | 'DOUBLE_FLAT' | 'NaTURAL' | 'FLAG_1' | 'FLAG_2' | 'REST_WHOLE' | 'REST_HALF' | 'REST_QUARTER' | 'REST_EIGHTH' | 'REST_SIXTEENTH' | 'REST_32ND'; export declare class SNChordLayer { /** SVG group 元素,作为内容的容器 */ static el: SVGGElement; /** 和弦层map,用于存储和弦层元素,key为音符index用于定位,value为和弦层元素 */ static chordMap: Map<number, SVGElement>; static defaultChordPositions: null[]; constructor(svg: SVGElement); static addChord(note: SNNote): void; static removeChord(note: SNNote): void; static destroyed(): void; } export declare enum SNChordType { Default = "default", Guitar = "guitar" } export declare class SNConfig { static width: number; static height: number; static content: SNContentOptions; static info: SNInfoOptions; static score: SNScoreOptions; static debug: SNDebugOptions; constructor(container: HTMLDivElement, options?: SNOptions); /** * 更新配置 * @param options */ static update(options: SNOptions): void; static reset(options?: SNOptions): void; } /** * SNContent 类 - 简谱内容的容器组件 * * @class SNContent * @extends {SNBox} * @description * 这个类是简谱渲染的主要容器组件,负责管理和协调信息区域和谱面区域的渲染。 * 它继承自 SNBox,具有基本的布局和边界框功能。 */ export declare class SNContent extends SNBox { /** SVG group 元素,作为内容的容器 */ el: SVGGElement; /** 信息区域组件实例 */ info: SNInfo | undefined; /** 谱面区域组件实例 */ score: SNScore | undefined; /** * 创建一个新的内容容器实例 * * @param svg - 父级 SVG 元素 * @param options - 内容区域的配置选项 * @description * 构造函数会: * 1. 初始化容器的尺寸和内边距 * 2. 创建 SVG group 元素 * 3. 绘制调试边界框(如果启用) * 4. 初始化信息和谱面区域 */ constructor(root: SimpleNotation, options: SNContentOptions); /** * 绘制信息区域内容 * * @param options - 要显示的信息数据 * @description * 使用提供的数据更新信息区域的显示内容 */ drawInfo(options: SNDataInfo): void; /** * 绘制谱面内容 * * @description * 使用提供的谱面数据更新谱面区域的显示内容 */ drawScore(): void; destroyed(): void; } /** * 内容区域配置。 * @property {number | number[]} padding - 区域内边距。 * @property {boolean} infoShow - 是否显示信息区域。 */ export declare interface SNContentOptions { padding: number | number[]; infoShow: boolean; } /** * 用于渲染内容的数据类型,可以是模板对象或字符串。 * @typedef {SNTemplate | string} SNData */ export declare type SNData = SNTemplate | string; /** * 简谱基本信息。 * @property {string} title - 标题。 * @property {string} [composer] - 作曲。 * @property {string} [lyricist] - 作词。 * @property {string} [beat] - 每小节几拍。 * @property {string} [time] - 每拍时值。 * @property {string} [key] - 调号。 * @property {string} [tempo] - 速度。 * @property {string} [author] - 作者。 */ export declare interface SNDataInfo { title: string; composer?: string; lyricist?: string; beat?: string; time?: string; key?: SNTemplateKey | SNAbcKey; tempo?: string; author?: string; } /** * 简谱数据类型枚举。 * @enum {string} * @property {string} TEMPLATE - 默认模板写法。 * @property {string} ABC - abc写法。 */ export declare enum SNDataType { TEMPLATE = "template", ABC = "abc" } /** * 调试模式下的边框盒子配置。 * @property {object} [borderbox] - 各区域边框盒子配置。 */ export declare interface SNDebugOptions { borderbox?: { content?: SNBorderBoxOptions; info?: SNBorderBoxOptions; score?: SNBorderBoxOptions; stave?: SNBorderBoxOptions; measure?: SNBorderBoxOptions; note?: SNBorderBoxOptions; }; } /** * SNEvent 类 - 事件系统核心实现 * * @class SNEvent * @description * 这个类负责管理事件系统,包括事件的订阅、取消订阅和触发。 * 它使用单例模式确保整个应用中只有一个事件系统实例。 */ export declare class SNEvent { private static instance; private eventCallbacks; private constructor(); /** * 获取 SNEvent 单例实例 */ static getInstance(): SNEvent; /** * 订阅事件 * @param event 事件名称,支持标准 DOM 事件和自定义事件(格式:object:action) * @param callback 回调函数 */ on(event: string, callback: EventCallback): void; /** * 取消订阅事件 * @param event 事件名称 * @param callback 回调函数 */ off(event: string, callback: EventCallback): void; /** * 触发事件 * @param event 事件名称 * @param detail 事件详情 */ emit(event: string, detail: EventDetail): void; /** * 清除所有事件监听 */ clear(): void; /** * 销毁事件系统 */ destroy(): void; } /** * 展开音符配置,继承自SNNoteOptions,增加measureIndex、repeatStart和repeatEnd字段。 * @property {number} measureIndex - 当前音符所在小节的索引。 * @property {boolean} [repeatStart] - 是否为循环开始音符。 * @property {boolean} [repeatEnd] - 是否为循环结束音符。 */ export declare type SNFlattenNoteOptions = SNNoteOptions & { measureIndex: number; repeatStart?: boolean; repeatEnd?: boolean; }; /** * 装饰音配置,继承自SNNoteOptions,去除部分字段。 */ export declare type SNGraceNoteOptions = Pick<SNNoteOptions, 'note' | 'upDownCount' | 'octaveCount' | 'underlineCount' | 'duration' | 'nodeTime'>; /** * SNInfo 类 - 简谱信息区域组件 * * @class SNInfo * @extends {SNBox} * @description * 这个类负责渲染简谱的信息区域,包括标题、作曲者、作词者、 * 调号、拍号、速度等元数据信息。它继承自 SNBox,具有基本的 * 布局和边界框功能。 */ export declare class SNInfo extends SNBox { /** SVG group 元素,作为信息区域的容器 */ el: SVGGElement; /** * 创建一个新的信息区域实例 * * @param content - 父级内容容器组件 * @param options - 信息区域的配置选项 * @description * 构造函数会: * 1. 初始化区域的尺寸和内边距 * 2. 创建 SVG group 元素 * 3. 绘制调试边界框(如果启用) * 4. 初始化空的信息显示 */ constructor(content: SNContent, options: SNInfoOptions); /** * 绘制标题 * * @param title - 简谱标题 * @returns {SVGTextElement | undefined} 创建的文本元素或 undefined * @description * 在信息区域中央绘制大号标题文本 */ drawTitle(title: string): SVGTextElement | undefined; /** * 绘制作词作曲作谱信息组 * * @param composer - 作曲者名称 * @param lyricist - 作词者名称 * @param author - 作者名称 * @returns {SVGTextElement | undefined} 创建的文本元素组 * @description * 在信息区域右下方绘制作词作曲信息,两行左对齐,整体右对齐 */ private drawCreatorInfo; /** * 解析调号字符串,返回符号和主音字母 * @param key - 调号字符串,如C#、Db、Emin等 * @returns { symbol: 'sharp' | 'flat' | undefined, letter: string, isMinor: boolean } */ private parseKeySignature; /** * 绘制调号和速度信息组 */ private drawMusicInfo; /** * 绘制所有信息 * * @param options - 包含所有信息字段的数据对象 * @description * 根据提供的数据绘制完整的信息区域,包括标题、作者信息、 * 调号、拍号和速度等。如果某个字段为空,对应的信息将不会绘制。 */ draw(options?: SNDataInfo): void; } /** * 信息区域配置。 * @property {number} height - 区域高度。 * @property {number | number[]} padding - 区域内边距。 */ export declare type SNInfoOptions = { height: number; padding: number | number[]; }; export declare class SNLoader { /** * 加载简谱数据并重新渲染 * * @param data - 简谱数据,包含谱面信息和音符数据 * @param type - 数据类型,默认为模板写法(template),可选abc写法 * @description * 这个方法会完全重新加载数据并重绘整个简谱。它会: * 1. 更新运行时配置 * 2. 清除现有内容 * 3. 重新创建内容组件 * 4. 绘制信息区域 * 5. 绘制谱面内容 */ static loadData(data: SNData, type?: SNDataType): void; static loadAbcData(data: string): void; static loadTemplateData(data: SNTemplate): void; } /** * SNMeasure 类 - 简谱小节渲染组件 * * @class SNMeasure * @extends {SNBox} * @description * 这个类负责渲染简谱中的一个小节,包括小节序号和所有音符。 * 它会根据权重自动计算每个音符的位置和宽度,确保音符间距 * 的合理性。 */ export declare class SNMeasure extends SNBox { /** SVG group 元素,作为小节的容器 */ el: SVGGElement; /** 当前小节的序号(从1开始) */ index: number; /** 小节的原始数据字符串 */ measureData: string; /** 小节的总权重(用于计算宽度) */ weight: number; /** 小节中所有音符的配置选项 */ noteOptions: SNNoteOptions[]; /** 小节中所有音符的实例 */ notes: SNNote[]; /** 小节在画布上的水平位置 */ x: number; /** 小节的实际宽度(像素) */ width: number; /** 小节的配置选项(包含repeatStart/repeatEnd等) */ options: SNMeasureOptions; /** * 创建一个新的小节实例 * * @param stave - 父级乐句组件 * @param options - 小节的配置选项 * @description * 构造函数会: * 1. 初始化小节的位置和大小 * 2. 设置基本属性(序号、数据等) * 3. 创建 SVG group 元素 * 4. 绘制调试边界框(如果启用) * 5. 开始渲染小节内容 */ constructor(stave: SNStave, options: SNMeasureOptions); /** * 绘制小节序号 * * @description * 在小节的左上角绘制小节序号,用于标识小节的顺序。 * 序号使用小号字体显示,避免干扰谱面的主要内容。 */ drawCount(): void; /** * 绘制完整的小节 * * @description * 完整的小节渲染流程: * 1. 绘制小节序号 * 2. 计算单位宽度(每个权重对应的像素值) * 3. 遍历所有音符配置 * 4. 计算每个音符的位置和宽度 * 5. 创建并渲染音符 */ draw(): void; } /** * 小节配置。 * @property {number} index - 当前是第几个小节。 * @property {string} measureData - 当前小节的原始数据。 * @property {number} weight - 小节权重。 * @property {SNNoteOptions[]} noteOptions - 小节内音符配置。 * @property {number} x - 小节x轴坐标。 * @property {number} width - 小节宽度。 * @property {boolean} [repeatStart] - 是否为循环开始小节。 * @property {boolean} [repeatEnd] - 是否为循环结束小节。 */ export declare interface SNMeasureOptions { index: number; measureData: string; weight: number; noteOptions: SNNoteOptions[]; x: number; width: number; repeatStart?: boolean; repeatEnd?: boolean; } export declare type SNMultiNoteOptions = Pick<SNNoteOptions, 'note' | 'upDownCount' | 'octaveCount'>; export declare type SNMusicSymbol = SNBravuraMusicSymbol | SNUnicodeMusicSymbol; export declare interface SNMusicSymbolOptions { x: number; y: number; fontSize?: number; dx?: string; dy?: string; fontFamily?: string; textAnchor?: string; } export declare type SNMusicSymbolType = 'bravura' | 'unicode'; /** * SNNote 类 - 简谱音符渲染组件 * * @class SNNote * @extends {SNBox} * @description * 这个类负责渲染简谱中的单个音符,包括音符本身、时值线(下划线) * 和对应的歌词(如果有)。 * * │< lineWeight >│ * ┌────────────────────┐ * │chordHeight │ * ├────────────────────┤ * │lineHeight │ * ├────────────────────┤ * │lyricHeight │ * ├────────────────────┤ * │chordLineHeight │ * └────────────────────┘ */ export declare class SNNote extends SNBox { /** SVG group 元素,作为音符的容器 */ el: SVGGElement; /** 当前音符的序号(从1开始) */ index: number; /** 音符的原始数据字符串 */ noteData: string; /** 音符的权重(用于计算宽度) */ weight: number; /** 音符的实际内容(数字或符号) */ note: string; /** 音符的实际时值 */ nodeTime: number; /** 标记是否为小节起始音符 */ startNote: boolean; /** 标记是否为小节结束音符 */ endNote: boolean; /** 音符下方的下划线数量(表示时值) */ underlineCount: number; /** 音符上方的升降号数量 */ upDownCount: number; /** 音符的八度升降数量 */ octaveCount: number; /** 是否附点音符 */ isDelay: boolean; /** 标记是否为连音的起始音符 */ isTieStart: boolean; /** 标记是否为连音的结束音符 */ isTieEnd: boolean; /** 标记是否为三连音音符 */ isTriplet: boolean; /** 标记是否为三连音的起始音符 */ isTripletStart: boolean; /** 标记是否为三连音的结束音符 */ isTripletEnd: boolean; /** 音符在画布上的水平位置 */ x: number; /** 音符的实际宽度(像素) */ width: number; /** 装饰音列表 */ graceNotes: SNGraceNoteOptions[]; /** 多音符列表 */ multiNotes: SNMultiNoteOptions[]; /** * 是否为时值错误音符(超出小节拍数时为true) */ isError: boolean; /** * 该音符上方的和弦标记(如有) */ chord?: string[]; /** 音符在原始文本中的起始位置 */ startPosition?: number; /** 音符在原始文本中的结束位置 */ endPosition?: number; /** 是否有左括号 */ hasLeftBracket?: boolean; /** 是否有右括号 */ hasRightBracket?: boolean; /** * 创建一个新的音符实例 * * @param measure - 父级小节组件 * @param options - 音符的配置选项 * @description * 构造函数会: * 1. 初始化音符的位置和大小 * 2. 设置基本属性(序号、内容等) * 3. 创建 SVG group 元素 * 4. 绘制调试边界框(如果启用) * 5. 开始渲染音符内容 */ constructor(measure: SNMeasure, options: SNNoteOptions); /** * 获取音符在原始文本中的范围 * @returns [start, end] 元组,表示音符在原始文本中的起始和结束位置 */ getTextRange(): [number | undefined, number | undefined]; /** * 绘制音符的升降号 * * @description * 根据 upDownCount 的值,在音符左上角绘制相应数量的升号(#)或降号(b)。 * 正数绘制升号,负数绘制降号。当有多个升降号时,使用重升号和重降号。 */ drawUpDownCount(options: { x: number; y: number; offset?: number; count?: number; fontSize?: number; fontHeight?: number; }): void; /** * 绘制音符的八度升降点 * * @description * 根据 octaveCount 的值,在音符正上方或正下方绘制相应数量的点。 * 正数在上方绘制,负数在下方绘制。 */ drawOctaveCount(options: { x: number; y: number; count?: number; r?: number; gap?: number; upOffset?: number; downOffset?: number; }): void; drawGraceNote(): void; /** * 绘制左右括号 * * @description * 根据 hasLeftBracket 和 hasRightBracket 字段,在音符左右两侧绘制括号,避免与音符本体重叠。 */ drawBrackets(): void; drawSimpleNote(): void; drawGuitarNote(): void; drawGuitarRestNote(lineTop: number, lineHeight: number): void; draw(): void; } /** * 音符事件详情类型 */ export declare interface SNNoteEventDetail extends EventDetail { /** 音符索引 */ index: number; /** 音符实例 */ note: SNNote; } /** * 音符配置。 * @property {number} index - 当前是第几个音符。 * @property {string} noteData - 当前音符的原始数据。 * @property {number} weight - 当前音符的权重。 * @property {string} note - 当前音符。 * @property {boolean} startNote - 是否是起始音符。 * @property {boolean} endNote - 是否是终止音符。 * @property {number} underlineCount - 下划线数量。 * @property {number} x - x轴坐标。 * @property {number} width - 宽度。 * @property {number} upDownCount - 升降数量。 * @property {number} octaveCount - 八度数量。 * @property {boolean} isTieStart - 是否是连音起始音符。 * @property {boolean} isTieEnd - 是否是连音终止音符。 * @property {SNGraceNoteOptions[]} graceNotes - 装饰音。 * @property {boolean} isError - 是否为时值错误音符。 * @property {string} [chord] - 和弦标记。 * @property {number} duration - 音符时值。 * @property {number} nodeTime - 音符占用拍数。 * @property {number} startPosition - 音符起始位置。 * @property {number} endPosition - 音符结束位置。 * @property {boolean} [isTriplet] - 是否为三连音音符。 * @property {boolean} [tripletGroupStart] - 是否为三连音组首音。 * @property {boolean} [tripletGroupEnd] - 是否为三连音组末音。 * @property {boolean} [hasLeftBracket] - 是否有左括号。 * @property {boolean} [hasRightBracket] - 是否有右括号。 */ export declare interface SNNoteOptions { index?: number; noteData: string; weight: number; note: string; startNote?: boolean; endNote?: boolean; underlineCount: number; x?: number; width?: number; upDownCount: number; octaveCount: number; isTieStart: boolean; isTieEnd: boolean; graceNotes: SNGraceNoteOptions[]; multiNotes: SNMultiNoteOptions[]; isError?: boolean; chord?: string[]; duration: number; isDelay: boolean; nodeTime: number; startPosition?: number; endPosition?: number; isTriplet?: boolean; tripletGroupStart?: boolean; tripletGroupEnd?: boolean; hasLeftBracket?: boolean; hasRightBracket?: boolean; } /** * 简谱渲染器初始化配置项。 * @property {number} [width] - 渲染区域宽度。 * @property {number} [height] - 渲染区域高度。 * @property {SNContentOptions} [content] - 内容区域配置。 * @property {SNInfoOptions} [info] - 信息区域配置。 * @property {Partial<SNScoreOptions>} [score] - 总谱区域配置。 * @property {boolean} [debug] - 是否开启调试模式。 * @property {boolean} [resize] - 是否自动监听容器尺寸变化并自适应。 */ export declare interface SNOptions { width?: number; height?: number; content?: SNContentOptions; info?: SNInfoOptions; score?: Partial<SNScoreOptions>; debug?: boolean; resize?: boolean; } /** * 简谱播放器,实例成员方式,自动从 SNRuntime 获取数据 * 支持播放、暂停、继续、停止等控制,回调获取当前播放音符 * 延音线('-')合并播放:前一个音符播放时长累加,onPointerMove每个音符都回调 * onNotePlay 只在非'-'音符时回调,参数为note和合并延音后的总时长(ms) */ export declare class SNPlayer { private notes; private tempo; private timer; private isPlaying; private isPaused; private currentIndex; private onPointerMoveCallbacks; private onEndCallbacks; private onNotePlayCallbacks; private onChordPlayCallbacks; /** * 当前循环播放的次数 (从1开始) */ private currentRepeatPass; /** * 遇到后反复记号,记录当前音符index+1,用于遇到分段直接跳到该index */ private repeatNextIndex; private currentTime; /** * 构造函数,自动从 SNRuntime 获取乐谱和速度 */ constructor(); /** * 拍平成音符队列,保留原顺序,并为每个音符附加其所属小节的repeat信息 */ private flattenNotes; /** * 获取当前音符列表 * @returns 当前音符列表 */ getNotes(): SNFlattenNoteOptions[]; /** * 注册光标移动回调(每个音符都回调,包括'-') * @param cb 回调函数,参数为当前播放的音符数据 */ onPointerMove(cb: (note: SNNoteOptions, currentTime: number) => void): () => void; /** * 注册播放结束回调 * @param cb 回调函数 */ onEnd(cb: () => void): () => void; /** * 注册实际发声回调(仅非'-'音符,参数为note和合并延音后的总时长ms) * @param cb 回调函数 (note, durationMs) */ onNotePlay(cb: (note: SNNoteOptions, duration: number) => void): () => void; /** * 注册和弦播放回调(每个音符都回调,参数为note和合并延音后的总时长ms) * @param cb 回调函数 (note, durationMs) */ onChordPlay(cb: (note: SNNoteOptions, duration: number) => void): () => void; /** * 跳转到指定音符 * @param index 设置当前播放index */ setCurrentIndex(index: number): void; /** * 开始播放,从头或当前进度播放 */ play(): void; /** * 暂停播放,保留当前进度 */ pause(): void; /** * 继续播放,从暂停处继续 */ resume(): void; /** * 停止播放,重置进度和循环状态 */ stop(): void; /** * 计算当前音符的时值(ms),直接使用parser解析得到的nodeTime(已包含附点和各种时值) * @param note 当前音符 * @returns 时值(毫秒) */ private getNoteDuration; /** * 判断两个音高是否完全一致(note、upDownCount、octaveCount) */ private isNotePitchEqual; /** * 调度下一个音符的播放,支持延音线、连音线合并播放和小节循环(repeatStart/repeatEnd) * onPointerMove每个音符都回调,onNotePlay只在非'-'且非连音线中间音符时回调 */ private scheduleNext; /** * 播放结束,重置状态并触发回调 */ private finish; } /** * 表示一个二维坐标点。 * @property {number} x - x轴坐标。 * @property {number} y - y轴坐标。 */ export declare interface SNPoint { x: number; y: number; } export declare class SNPointerLayer { /** SVG root元素 */ static svg: SVGElement; /** SVG group 元素,作为内容的容器 */ static el: SVGGElement; /** 播放指针矩形 */ static pointerRect: SVGRectElement | null; /** 存储音符和矩形的对应关系 */ static noteRectMap: Map<number, SVGRectElement>; /** 存储音符实例的对应关系 */ static noteInstanceMap: Map<number, SNNote>; /** 事件系统实例 */ static event: SNEvent; /** 存储选中音符矩形的对应关系 */ static selectedNoteRectMap: Map<number[], SVGRectElement>; /** 播放指针颜色 */ private static readonly POINTER_COLOR; /** 交互指针颜色 */ private static readonly HOVER_COLOR; /** 指针圆角大小 */ private static readonly ROUND_RADIUS; /** * 初始化指针层 * @param svg SVG容器元素 */ constructor(svg: SVGElement); /** * 初始化播放光标 */ private static initPointer; /** * 创建音符的交互矩形 */ static createNoteRect(note: SNNote): SVGRectElement; /** * 显示指定音符的矩形 */ static showNoteRect(index: number): void; /** * 隐藏指定音符的矩形 */ static hideNoteRect(index: number): void; /** * 清除所有音符矩形 */ static clearNoteRects(): void; /** * 清除所有选中高亮矩形 */ static clearSelectedNoteHighlights(): void; /** * 根据文本范围获取包含在该范围内的音符索引列表,并按行分组 * @param start - 文本选中范围的起始位置 * @param end - 文本选中范围的结束位置 * @returns 按行分组的音符索引二维数组 */ static getNoteIndicesInTextRange(start: number, end: number): number[][]; /** * 计算一组音符的联合边界框 * @param indices - 音符索引数组 * @returns 包含 x, y, width, height 的边界框对象,如果数组为空则返回null */ private static getCombinedBBox; /** * 绑定事件 */ private static bindEvents; /** * 显示/移动播放光标 * @param noteTag sn-tag属性值,如'note-1' * @param svgRoot SVG根节点 */ static showPointer(noteTag: string): void; /** * 清除播放光标 */ static clearPointer(): void; /** * 销毁 */ static destroy(): void; /** * 更新选中高亮 * @param groupedNoteIndices 需要高亮的音符索引二维数组(已按行分组) */ static updateSelectionHighlight(groupedNoteIndices: number[][]): void; } export declare class SNRuntime { static info: SNDataInfo; static score: string; static parsedScore: SNStaveOptions[]; static lyric: string; static splitLyrics: (string | string[])[]; static type: SNDataType; /** * 构造函数,根据type选择不同的数据解析方式 * @param data - 简谱数据 * @param type - 数据类型,默认为模板写法 */ constructor(options: SNRuntimeOptions); static getTitle(): string; /** * 清除现有内容 */ static clear(): void; /** * 拆分歌词片段: * 1. 英文单词整体为一个音(以空格分割) * 2. 括号包裹内容整体为一个音(支持中英文括号) * 3. 标点附加到前一个音 * 4. 其它字符(如中文)按单字处理 * @param fragment 歌词片段 * @returns 拆分后的数组 */ private static splitLyricFragment; /** * 拆分歌词,支持普通单行和竖排多行歌词格式。 * 1. 普通字符串按单字、英文单词、-、逗号等规则拆分 * 2. 遇到连续的 [1.内容][2.内容][3.内容] 结构时, * 自动按竖排多行歌词合并为数组,数组下标为行号-1 * 例如: * 我的[1.第一部分][2.第二部分][3.第三部分]都结束了 * => ['我','的',['第','第','第'],['一','二','三'],'都','结','束','了'] * @param lyric 原始歌词字符串 * @returns 拆分后的歌词数组,单字或竖排多行数组 */ static splitLyric(lyric: string): (string | string[])[]; } /** * 简谱运行时的核心配置。 * @property {SNDataInfo} info - 简谱的基本信息。 * @property {string} score - 原始乐谱字符串。 * @property {SNStaveOptions[]} parsedScore - 解析后的乐句数组。 * @property {string} lyric - 歌词字符串。 * @property {(string | string[])[]} splitLyrics - 拆分后的歌词。 * @property {SNDataType} type - 简谱数据类型。 */ export declare type SNRuntimeOptions = { info: SNDataInfo; score: string; parsedScore: SNStaveOptions[]; lyric: string; splitLyrics: (string | string[])[]; type: SNDataType; }; /** * SNScore 类 - 简谱谱面渲染组件 * * @class SNScore * @extends {SNBox} * @description * 这个类负责解析和渲染简谱的谱面内容,包括音符、小节线、 * 连音线等。它会自动处理分行和布局,确保谱面美观易读。 */ export declare class SNScore extends SNBox { /** SVG group 元素,作为谱面的容器 */ el: SVGGElement; /** 五线谱选项数组,用于存储每行谱表的配置 */ staveOptions: SNStaveOptions[]; /** 五线谱实例数组,存储已渲染的谱表 */ staves: SNStave[]; /** 当前处理的音符总数 */ noteCount: number; /** * 创建一个新的谱面实例 * * @param content - 父级内容容器组件 * @param options - 谱面的配置选项 * @description * 构造函数会: * 1. 计算并设置谱面区域的位置和大小 * 2. 创建 SVG group 元素 * 3. 绘制调试边界框(如果启用) */ constructor(content: SNContent, options: SNScoreOptions); /** * 绘制完整的谱面 * * @param scoreData - 谱面的原始字符串数据 * @description * 完整的谱面渲染流程: * 1. 解析谱面数据 * 2. 计算每个谱表的位置 * 3. 创建并渲染所有谱表 * 4. 处理歌词显示(如果有) */ draw(): void; } /** * 总谱区域配置。 * @property {number | number[]} padding - 区域内边距。 * @property {number} lineHeight - 每行高度。 * @property {number} lineSpace - 每行间距。 * @property {number} lyricHeight - 歌词行高。 * @property {number} chordHeight - 和弦/强弱符号高度。 * @property {number} lineWeight - 每行歌词权重。 * @property {number} allowOverWeight - 每行歌词允许的溢出权重。 * @property {SNChordType} chordType - 和弦显示类型。 * @property {SNScoreType} scoreType - 总谱显示类型。 * @property {boolean} showChordLine - 是否显示和弦线。 * @property {number} chordLineHeight - 和弦线高度。 */ export declare interface SNScoreOptions { padding: number | number[]; lineHeight: number; lineSpace: number; lyricHeight: number; chordHeight: number; lineWeight: number; allowOverWeight: number; chordType: SNChordType; scoreType: SNScoreType; showChordLine: boolean; chordLineHeight: number; } export declare enum SNScoreType { Simple = "simple", Guitar = "guitar", SimpleGuirar = "simple-guitar" } /** * SNStave 类 - 简谱乐句(谱表)渲染组件 * * @class SNStave * @extends {SNBox} * @description * 这个类负责渲染简谱中的一个乐句(谱表),包括小节线、 * 结束线等。它会根据权重自动计算每个小节的宽度,并确保 * 整体布局的合理性。 */ export declare class SNStave extends SNBox { /** SVG group 元素,作为乐句的容器 */ el: SVGGElement; /** 当前乐句的索引号(从1开始) */ index: number; /** 乐句的总权重(用于计算宽度) */ weight: number; /** 当前乐句中所有小节的配置选项 */ measureOptions: SNMeasureOptions[]; /** 当前乐句中所有小节的实例 */ measures: SNMeasure[]; /** 乐句在画布上的垂直位置 */ y: number; /** 标记是否为最后一个乐句 */ endLine: boolean; /** 小节线预留宽度(像素) */ static BAR_LINE_WIDTH: number; /** * 创建一个新的乐句实例 * * @param score - 父级谱面组件 * @param options - 乐句的配置选项 * @description * 构造函数会: * 1. 初始化乐句的位置和大小 * 2. 设置基本属性(索引、权重等) * 3. 计算实际宽度 * 4. 创建 SVG group 元素 * 5. 绘制调试边界框(如果启用) * 6. 开始渲染乐句内容 */ constructor(score: SNScore, options: SNStaveOptions); /** * 绘制乐句结束线 * * @description * 在乐句末尾绘制结束线。如果是整个谱面的最后一个乐句, * 会绘制双线(粗线)表示终止。结束线的高度与五线谱线 * 保持一致。 */ drawMeasureEndLine(x: number): void; /** * 绘制repeat开始线(左粗右细+右两点) */ drawRepeatStartLine(x: number, yTop: number, yBottom: number): void; /** * 绘制repeat结束线(左细右粗+左两点) */ drawRepeatEndLine(x: number, yTop: number, yBottom: number): void; /** * 绘制普通小节线 */ drawBarLine(x: number, yTop: number, yBottom: number): void; /** * 绘制完整的乐句 * * @description * 完整的乐句渲染流程: * 1. 计算单位宽度(每个权重对应的像素值) * 2. 遍历所有小节配置 * 3. 计算每个小节的位置和宽度 * 4. 创建并渲染小节 * 5. 绘制小节左侧的线 * 6. 如果小节有repeatEnd标记,绘制右侧的repeat结束标记 * 7. 最后绘制整个乐句的结束线(如果最后一个小节没有repeatEnd) * * 特殊处理: * 如果当前乐句为最后一行且只有一个小节,则该小节宽度自适应内容宽度,不再强行撑满整行。 */ draw(): void; } /** * 乐句配置。 * @property {number} index - 当前是第几个乐句。 * @property {number} weight - 乐句总权重。 * @property {SNMeasureOptions[]} measureOptions - 当前乐句每个小节的内容。 * @property {number} y - 当前乐句的y轴坐标。 * @property {boolean} endLine - 当前乐句是否是最后一行。 */ export declare interface SNStaveOptions { index: number; weight: number; measureOptions: SNMeasureOptions[]; type: SNStaveType; y: number; endLine: boolean; } export declare enum SNStaveType { DefaultLine = "default-line", ChordLine = "chord-line" } /** * SVG分组元素配置。 * @property {string} tag - 分组标签名。 */ export declare interface SNSvgGOptions { tag: string; } /** * SVG直线元素配置。 * @property {number} x1 - 起点x坐标。 * @property {number} y1 - 起点y坐标。 * @property {number} x2 - 终点x坐标。 * @property {number} y2 - 终点y坐标。 * @property {string} [stroke] - 线条颜色。 * @property {number} [strokeWidth] - 线条宽度。 */ export declare interface SNSvgLineOptions { x1: number; y1: number; x2: number; y2: number; stroke?: string; strokeWidth?: number; } export declare interface SNSvgRectOptions { x: number; y: number; width: number; height: number; rx?: number; ry?: number; stroke?: string; strokeWidth?: number; fill?: string; } /** * SVG文本元素配置。 * @property {number} x - 文本x轴坐标。 * @property {number} y - 文本y轴坐标。 * @property {string} [text] - 文本内容。 * @property {number} [fontSize] - 字体大小。 * @property {string} [fontFamily] - 字体。 * @property {string} [fontWeight] - 字重。 * @property {string} [stroke] - 描边颜色。 * @property {number} [strokeWidth] - 描边宽度。 * @property {string} [textAnchor] - 对齐方式。 */ export declare interface SNSvgTextOptions { x: number; y: number; dx?: string; dy?: string; text?: string; fontSize?: number; fontFamily?: string; fontWeight?: string; fill?: string; stroke?: string; strokeWidth?: number; textAnchor?: string; } export declare type SNSvgTspanOptions = Partial<SNSvgTextOptions>; /** * 简谱模板对象。 * @property {SNDataInfo} info - 简谱基本信息。 * @property {string} score - 乐谱内容。 * @property {string} [lyric] - 歌词内容。 */ export declare interface SNTemplate { info: SNDataInfo; score: string; lyric?: string; } export declare type SNTemplateKey = 'C' | 'D' | 'E' | 'F' | 'G' | 'A' | 'B' | 'C#' | 'D#' | 'E#' | 'F#' | 'G#' | 'A#' | 'B#' | 'Cb' | 'Db' | 'Eb' | 'Fb' | 'Gb' | 'Ab' | 'Bb'; export declare class SNTieLineLayer { static tieStartNotes: SNNote[]; static tripletStartNotes: SNNote[]; private static el; constructor(scoreEl: SVGGElement); /** * 记录连音的起始音符 * @param note - 连音的起始音符 */ static recordTieStart(note: SNNote): void; /** * 记录三连音组的首音符 * @param note - 三连音组的首音符 */ static recordTripletStart(note: SNNote): void; /** * 绘制单条连音线(两端为四分之一圆弧,中间为直线,半径自适应,且不与音符重叠) * @param x1 - 起始x坐标 * @param y1 - 起始y坐标 * @param x2 - 结束x坐标 * @param y2 - 结束y坐标 * @param xDistance - x方向距离 */ private static drawSingleTieLine; /** * 绘制连音线并移除已使用的起始音符记录 * @param endNote - 连音的结束音符 */ static drawTieLineFromRecord(endNote: SNNote): void; /** * 绘制三连音连音线(beam):两端为四分之一圆弧,中间为直线,数字3位于横线上方 * @param endNote - 三连音的最后一个音符 */ static drawTripletBeamByRecord(endNote: SNNote): void; } /** * 乐谱和乐器之间转换的工具类 */ export declare class SNTransition { /** * 简谱数字没有上下八度符号时的默认八度音高 */ static baseOctave: number; /** * 简谱数字1-7和对应的音名映射 */ static scaleMap: string[]; /** * 定义简谱音符1-7的基本MIDI值 (假设1是C4, MIDI 60) */ static baseSimpleNoteMidis: { '1': 60; '2': 62; '3': 64; '4': 65; '5': 67; '6': 69; '7': 71; '0': -1; }; /** * 定义调号转为移调时的数组映射 */ static transposeKeyMap: Record<string, number>; /** * 吉他弦和midi映射 */ static guitarTuningMidiMap: Record<string, number>; /** * 吉他弦和音名的映射 */ static guitarTuningNoteNameMap: Record<string, string>; /** * 通用的乐理/简谱数字转换方法 */ static General: { /** * 将音名(带八度)转换为 MIDI 值。 * @param {string} noteName - 音名字符串 (e.g., 'C4', 'D#4', 'Gb3'). * @returns {number | null} 对应的 MIDI 值或 null (无效音名). */ noteNameToMidi(noteName: string): number | null; /** * 将 MIDI 值转换为音名(带八度)。 * @param {number} midi - MIDI 值。 * @returns {string} 对应的音名字符串 (e.g., 'C4', 'D#4'). */ midiToNoteName(midi: number): string; /** * 将简谱数字和八度、升降号信息转换为音名 (e.g., '1' -> 'C4', '#2' -> 'D#4', '5(.') -> 'G3'). * @param {string} noteValue - 简谱数字字符串 (e.g., '1', '#2', '5'). * @param {number} octaveCount - 八度升降数量 (正数升八度, 负数降八度, 0不变)。 * @param {number} upDownCount - 升降号数量 (正数升半音, 负数降半音, 0不变)。 * @returns {string | null} 对应的音名字符串 (e.g., 'C4', 'D#4', 'G3') 或 null (休止符或无效音符)。 */ simpleNoteToNoteName(noteValue: string, octaveCount: number, upDownCount: number): string | null; noteNameToSimpleNote(noteName: string): string | null; noteNameToParsedNote(noteName: string): SNMultiNoteOptions | null; midiToParsedNote(midi: number): SNMultiNoteOptions | null; /** * 将 MIDI 值转换为 SimpleNotation 模板格式的音高字符串 (e.g., 60 -> "1", 61 -> "#1", 72 -> "^1"). * 仅处理音高信息,不考虑时值、休止符、小节线等。 * @param {number} midi - MIDI 值。 * @returns {string | null} SimpleNotation 格式的音高字符串,或 null (无效 MIDI 值)。 */ midiToSimpleNote(midi: number): string | null; /** * 获取当前调式的移调半音数(以C为0,D为2,E为4等) * 支持大调常用调式 * @param {string | undefined} key - 乐谱的主调调式字符串。 * @returns {number} 对应的移调半音数。 */ getTransposeByKey(key: string | undefined): number; }; /** * 吉他相关的转换方法 */ static Guitar: { /** * 查找给定 MIDI 音高在吉他指板上的所有可能位置。 * @param {number} midi - 音符的 MIDI 值(考虑了吉他低八度约定)。 * @param {number} [maxFret=17] - 最大查找品位。 * @returns {GuitarPosition[]} - 所有可能的品位/弦组合数组。 */ findAllPositionsForMidi(midi: number, maxFret?: number): GuitarPosition[]; /** * 查找给定 MIDI 音高在 capo 移调后的优先品位区域(例如 capo 品位到 capo 品位+3)内的位置。 * 如果 capo 为 0,则优先区域为 0-3 品。 * @param {number} midi - 音符的 MIDI 值(考虑了吉他低八度约定)。 * @param {number} transposeValue - 当前的移调(Capo)值。 * @param {number} [preferredFretRange=3] - 优先查找的品位范围(从 capo 品位开始)。 * @param {number} [maxFret=17] - 最大查找品位。 * @returns {GuitarPosition[]} - 优先区域内的品位/弦组合数组。 */ findPreferredPositionsForMidi(midi: number, transposeValue: number, preferredFretRange?: number, maxFret?: number): GuitarPosition[]; /** * 获取吉他和弦符号对应的吉他指板品位。 * @param {string} chordSymbol - 吉他和弦符号 (e.g., 'C', 'Am'). * @returns {(number | null)[] | undefined} 对应的品位数组 (6弦到1弦),null 表示不弹。 */ getChordFretPositions(chordSymbol: string): (number | null)[] | undefined; /** * 将吉他品位和弦号转换为音高数组。 * @param {(number | null)[]} fretPositions - 吉他指板品位数组 (6弦到1弦),null 表示不弹。 * @returns {string[]} 对应的音高字符串数组 (e.g., ['E2', 'A2', 'D3', 'G3', 'B3', 'E4']). */ fretPositionsToNoteNames(fretPositions: (n