spec.md 2.9 KB

ADDED Requirements

Requirement: FFT 频谱变换

系统 SHALL 提供 FFTAnalyzer 工具类,接收 1024 个 PCM 时域样本(number[]),通过 Cooley-Tukey 基 2 快速傅立叶变换算法计算出 512 个频率 bin 的幅值数组。

Scenario: 正常 FFT 计算

  • WHEN 调用 FFTAnalyzer.analyze(pcmData: number[], sampleRate: number)pcmData 长度为 1024
  • THEN 系统 SHALL 返回 SpectrumData 对象,包含 512 个频率 bin 的归一化幅值(0.0 ~ 1.0 范围)

Scenario: 输入数据为空

  • WHEN 调用 FFTAnalyzer.analyze(pcmData, sampleRate)pcmData 长度为 0
  • THEN 系统 SHALL 返回全零的 SpectrumData 对象

Requirement: Hann 窗函数预处理

FFT 计算前 SHALL 对输入 PCM 数据应用 Hann 窗函数,以减少频谱泄漏。

Scenario: 窗函数应用

  • WHEN 1024 个 PCM 样本进入 FFT 分析流程
  • THEN 系统 SHALL 将每个样本乘以对应位置的 Hann 窗系数 0.5 * (1 - cos(2π * n / N)),然后再执行 FFT

Requirement: 对数频率映射与频段聚合

系统 SHALL 将 512 个线性频率 bin 按对数刻度映射并聚合为 32 个可视化频段。

Scenario: 频段聚合输出

  • WHEN FFT 计算完成后调用 SpectrumData.getBands(bandCount: number)
  • THEN 系统 SHALL 返回 number[],长度等于 bandCount,每个元素为对应频率范围内所有 bin 幅值的平均值,归一化到 0.0 ~ 1.0

Scenario: 低频到高频覆盖

  • WHEN 采样率为 44100Hz,请求 32 个频段
  • THEN 频段 SHALL 按对数分布覆盖约 32Hz ~ 16000Hz 范围,低频区每个频段覆盖较窄的频率范围,高频区每个频段覆盖较宽的频率范围

Requirement: 指数平滑处理

系统 SHALL 对连续帧的频谱数据进行指数移动平均平滑,避免视觉跳变。

Scenario: 平滑衰减

  • WHEN 新一帧频谱数据到达
  • THEN 每个频段的输出值 SHALL 计算为 output = newValue * smoothUp + previousOutput * (1 - smoothUp)(上升时),或 output = newValue * smoothDown + previousOutput * (1 - smoothDown)(下降时),其中上升系数约 0.7,下降系数约 0.3,实现快速响应、缓慢衰减的视觉效果

Scenario: 首帧无历史数据

  • WHEN 第一帧频谱数据到达(无历史数据)
  • THEN 系统 SHALL 直接使用当前帧数据作为输出,不进行平滑

Requirement: 总体能量值计算

SpectrumData SHALL 提供 getEnergy(): number 方法,返回当前帧所有频段幅值的均方根值,归一化到 0.0 ~ 1.0,代表当前音频的整体响度/能量。

Scenario: 静音时能量为零

  • WHEN 所有 PCM 样本值均为 0
  • THEN getEnergy() SHALL 返回 0.0

Scenario: 正常播放时计算能量

  • WHEN 音频正常播放,频谱数据有效
  • THEN getEnergy() SHALL 返回一个介于 0.0 ~ 1.0 之间的值,反映当前帧的整体响度