@@ -356,13 +356,37 @@ function parseDurationString(
356356/**
357357 * 计算带附点的音符时值
358358 *
359- * @param noteValue - 基础音符时值
360- * @param dotCount - 附点数量
361- * @returns 带附点的音符时值
359+ * 附点规则:
360+ * - 单附点:原时值 + 原时值的一半 = 原时值 * 1.5
361+ * - 双附点:原时值 + 原时值的一半 + 原时值的四分之一 = 原时值 * 1.75
362+ * - 三附点:原时值 + 原时值的一半 + 原时值的四分之一 + 原时值的八分之一 = 原时值 * 1.875
363+ *
364+ * 通用公式:noteValue * (2 - Math.pow(0.5, dotCount))
365+ *
366+ * @param noteValue - 基础音符时值(相对于全音符的比例,如 1/4 表示四分音符)
367+ * @param dotCount - 附点数量(1表示单附点,2表示双附点等)
368+ * @returns 带附点的音符时值(相对于全音符的比例)
369+ *
370+ * @example
371+ * // 四分音符(1/4)带单附点,ticksPerWhole = 16
372+ * // noteValue = 1/4 = 0.25
373+ * // dottedValue = 0.25 * 1.5 = 0.375
374+ * // duration = 0.375 * 16 = 6 ticks(四分音符4ticks + 附点2ticks = 6ticks)
375+ *
376+ * @example
377+ * // 四分音符(1/4)带单附点,ticksPerWhole = 48
378+ * // noteValue = 1/4 = 0.25
379+ * // dottedValue = 0.25 * 1.5 = 0.375
380+ * // duration = 0.375 * 48 = 18 ticks(四分音符12ticks + 附点6ticks = 18ticks)
362381 */
363382function calculateDottedNoteValue ( noteValue : number , dotCount : number ) : number {
364383 if ( dotCount === 0 ) return noteValue ;
365- return noteValue * ( 1 + 0.5 * ( 1 - Math . pow ( 0.5 , dotCount ) ) ) ;
384+ // 正确的公式:每个附点增加前一个附点值的一半
385+ // 单附点:1 + 0.5 = 1.5
386+ // 双附点:1 + 0.5 + 0.25 = 1.75
387+ // 三附点:1 + 0.5 + 0.25 + 0.125 = 1.875
388+ // 通用公式:2 - Math.pow(0.5, dotCount)
389+ return noteValue * ( 2 - Math . pow ( 0.5 , dotCount ) ) ;
366390}
367391
368392/**
0 commit comments