Skip to content

异常处理

这里记录了一些可能的异常情况以及处理方式。

非法值:即 -nan(ind)inf 相当于 JS 的 NaNInfinity

事件之间的关系分析

以下内容基于版本 123 实测,不同版本可能存在差异。

预处理:自动排序

事件读取时,开始时间不同的自动按照时间从小到大排序;相同的不自动排序。

合法:相离和相切

相离和相切时,事件内正常插值,事件外采用上一个事件的结束值。

异常 1:初始时间

  • 非速度事件:第一个事件开始时间 t 不为 0 时,0~t 区间将采用第一个事件的解析延拓。

    • 举例:若第一个事件为正弦缓动,在该事件开始时间之前的行为将是正弦曲线。

    • 可能计算出非法值,让线不可见。

  • 速度事件:第一个事件开始时间 t 不为 0 时,0~t 区间将视为值为 0 的速度事件。

异常 2:重叠和包含

速度事件和非速度事件对重叠和包含的处理方式有所不同。

  • 非速度事件:后来居上,即后事件值覆盖前事件值。

    • 这里的覆盖准确来说是截断,即前事件在后事件开始时间之后的部分均被削除。

    • 即使后事件结束时间比前事件小也是如此,不存在后事件结束时恢复前事件值的情况。

    • 举例:设两相邻的 A,B 非速度事件的起止时间分别为 t1~t3,t2~t4t1<t2<t3

      • t1~t2 时间仅计算 A 事件,不受 B 事件影响

      • t2 时间以后仅计算 B 事件,不受 A 事件影响

  • 速度事件:先入为主,即前事件值覆盖后事件值。

    • 重叠部分视为负向的时间间隔“正常”计算,不会影响音符的相对位置。

    • 举例:设两相邻的 A,B 速度事件的起止时间分别为 t1~t3,t2~t4t1<t2<t3

      • t1~t3 时间仅计算 A 事件,不受 B 事件影响

      • t3 时间以后既累计了完整的 A 事件 + 正常累计 B 事件,还累计了 A 事件结尾值对 t3~t2 负向“间隔”的积分。

    • A 事件起止值相同,可以更简单地视为累计了 t1~t2A 事件 + 正常累计 B 事件。

    • 在因此产生的瞬移时刻,音符位置采用前值。

    • 根据 @点缀星空 花费了十几根头发的代价得出的结论,在此感谢 w

异常 3:起止时间

  • 开始时间大于结束时间

    • 非速度事件:视为起止时间均为开始时间,起止值均为结束值的瞬间事件。

    • 速度事件:视为起止时间均为开始时间,起止值均为结束值的瞬间事件,还累计了结束值与开始值的相反数对时间负向“间隔”的积分,即 vendvstart2(tstarttend)

异常 4:缓动切割

  • easingLeft 等于 easingRight :可能计算出非法值。

  • easingLefteasingRight 值小于 0 或大于 1 :可能计算出非法值。

    • RPE 点击该事件时将自动归位至 01

异常 5:线不透明度

  • 由于 RPE 的刻意设计,任何负数 alpha 都会使该线的音符完全隐藏

    • 打击特效/音效在编辑页也被隐藏,但在预览页仍然正常显示/播放。
  • 因为 alphaint 类型,超过 int 类型的限制将使 RPE 崩溃

  • 缓动事件结果会被取整,表现按取整结果计算。

    • 例如 -0.999 = 01.999 = 1

    • 非法值会被转换为 -2147483648

  • 因为 alpha 最大值 255 ,超过 255 表现为该值对 255 进行位与运算的结果。

    • 例如 256 = 02559 = 255
  • 由于 RPE 编辑页自带不透明度 0.6x(该值可在设置修改),编辑页实际还要先对结果乘以 0.6 再进行位与运算。

    • 例如 426 = 2554266667 = 0(仅编辑页)

WARNING

  • 注意:RPE 的 音符距离会随 bpm 变化而变化,但编辑页不会实时更新距离。

CC-BY-NC-4.0 Licensed