Files
AudioSystem/StartOffset 测试清单.md
T
Oliver 6e8e17ec44 feat: StartOffset
- 实现startOffset
- 修复EndOffset = 0 + 循环播放时,音乐会大量重复播放的错误。
- 增加数据校验和 BeatClock 联动。StartOffset不正确时停止bar+级 callback。
- BeatClock 现在会在每次重新播放时重启,以解决EndOffset配置错误被舍弃时,拍子对不上的问题。
2026-05-12 15:47:04 +08:00

84 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 测试清单
### 测试优先级
1. ~~**P0 冒烟**#1, #2, #5, #25(核心路径 + 回归)~~
2. ~~**P1 功能**#9, #10, #13, #14, #16, #20SyncPoint + BeatClock + Align~~
3. ~~ **P2 边界**#3, #4, #11, #18, #19, #23, #28, #29 ~~
4. **P3 回归**#6, #7, #8, #12, #15, #17, #21, #22, #26, #27, #30, #31
### 一、StartOffset 核心功能
| # | 测试场景 | 验证点 | 是否通过 |
|---|---------|-------|:--------:|
| 1 | 播放 StartOffset=5s 的 Segment | AudioClip 从 0 开始播放(可听到前奏);BeatClock 在 5s 后才触发第一次 Beat 回调 | ✅
| 2 | 播放 StartOffset=0 的 Segment | 行为与改动前完全一致 | ✅
| 3 | StartOffset + EndOffset 组合 | 播放到 `clip.length - EndOffset` 时 Segment 逻辑结束,物理播放继续到自然结束 | ✅
| 4 | StartOffset 值大于 Clip 长度 | 应有合理降级(当前为 TODO,至少不崩溃) | ✅
### 二、循环播放
| # | 测试场景 | 验证点 | 是否通过 |
|---|---------|--------|:--------:|
| 5 | LoopCount=-1StartOffset=5s | 第一轮从 0 播放;第二轮及之后从 5s 开始播放 | ✅
| 6 | LoopCount=2StartOffset=5s | 第一轮从 0 播放,第二轮从 5s 开始,播满 2 轮后停止 | ✅
| 7 | LoopCount=-1StartOffset=0 | 行为与改动前完全一致 | ✅
| 8 | 循环时 BeatClock | 每次循环 BeatClock 重新启动,逻辑时间从 0 重新开始计数 | ✅
### 三、SyncPoint.SameAsCurrentSegment
| # | 测试场景 | 验证点 | 是否通过 |
|---|---------|--------|:--------:|
| 9 | 旧 Segment StartOffset=5s,播放到 15s 时切换;新 Segment StartOffset=3s | 逻辑时长=15-5=10s;新位置=10+3=13s;新 AudioSource.timeSamples 对应 13s | ✅ |
| 10 | 旧 Segment StartOffset=5s,播放到 3s 时切换(还没过 StartOffset | 新 Segment 从自身 StartOffset 开始播放 | ✅ |
| 11 | 计算出新位置 < 新 StartOffset | 新 Segment 从自身 StartOffset 开始播放 | ✅
| 12 | 旧 Segment 无 StartOffset,新 Segment 有 StartOffset | 旧 SourceStartOffset=0,计算逻辑正确 |
### 四、SyncPoint.Start
| # | 测试场景 | 验证点 | 是否通过 |
|---|---------|--------|:--------:|
| 13 | StartOffset=5sFadeInTime=2s | AudioSource 从 3s 开始播放(5-2=3),淡入 2s 后刚好到 5s | ✅
| 14 | StartOffset=1sFadeInTime=3s | StartPlayTime=1-3=-2→0,从头开始淡入,忽略 StartOffset | ✅
| 15 | StartOffset=5sFadeInTime=0 | StartPlayTime=5,从 5s 开始播放(无淡入) | ✅
### 五、BeatClock 延迟启动
| # | 测试场景 | 验证点 | 是否通过 |
|---|---------|--------|:--------:|
| 16 | 首次启动 StartOffset=5s | BeatClock 等 5s 后才触发首次 Beat 回调 | ✅
| 17 | 首次启动 StartOffset=0 | BeatClock 立即启动,行为不变 |
| 18 | 延迟期间调用 Stop() | BeatClock 立即停止,不触发任何回调 | ✅
| 19 | SameAsCurrentSegment 切换时逻辑起点已过 | BeatClock 立即启动(delay<=0),从正确的逻辑时间继续 | 不会有 这个情况
### 六、对齐(AlignMode
| # | 测试场景 | 验证点 | 是否通过 |
|---|---------|--------|:--------:|
| 20 | AlignMode.BeatStartOffset=5s | 对齐基于逻辑起点(m_startDspTime = dspTime + 5),不是物理起点 | ✅
| 21 | AlignMode.BarStartOffset=5s | 同上 | ✅
| 22 | 在 StartOffset 延迟期间调用 GetNextDspTime | 返回 m_startDspTime(逻辑起点),不会返回过去的时间 | 要怎么测试?
### 七、Blend Container
| # | 测试场景 | 验证点 | 是否通过 |
|---|---------|--------|:--------:|
| 23 | Blend Container 的子 Segment 有 StartOffset | GetEffectiveStartOffset 返回 0isLoop=false,行为与改动前一致 | ✅
| 24 | SyncPoint.SameAsCurrentSegment 降级 | Blend 不支持 SameAsCurrentSegment,降级为 Start(原有行为不变) | ✅
### 八、回归测试(无 StartOffset 时行为不变)
| # | 测试场景 | 验证点 | 是否通过
|---|---------|--------|:---:|
| 25 | 所有 Segment 的 StartOffset=0EndOffset=0 | 全流程与改动前一致:播放、循环、切换、SyncPoint、FadeIn/Out | ✅
| 26 | Segment 只有 EndOffset,无 StartOffset | WaitSegmentFinish 到达 effectiveTime 后通知 container 推进 | ✅
| 27 | AmbienceChannelPlayer | 不涉及 BeatClockStartOffset 仅影响 PlaySegment 的 isLoop 跳转,需确认无副作用 | ✅
### 九、Sequence/Random Container 内多个 Segment
| # | 测试场景 | 验证点 | 是否通过 |
|---|---------|--------|:--------:|
| 28 | Sequence Container3 个 Segment 各有不同 StartOffset,首次播放 | 所有 Segment 从 0 开始播放 | ✅
| 29 | 同上,LoopCount=-1 | 第二轮起所有 Segment 从各自 StartOffset 开始 | ✅
| 30 | Random Container,循环时 | 选中 Segment 从其 StartOffset 开始 |
| 31 | Step Sequence Container | 每次切 Segment 时 isLoop 传递正确 |