feat(audio): 添加音频重采样支持,修复播放速度问题

问题:
- TTS 返回 16000 Hz 音频,但 Context 使用 44100 Hz
- 播放速度快 2.75 倍(44100/16000)
- 不同采样率的音频播放速度不正确

解决方案:
- 集成 gomplerate 库(纯 Go,零依赖)
- 自动检测音频采样率并重采样到 44100 Hz
- 支持任意采样率的音频文件正常播放

技术实现:
- resampler.go: 封装 gomplerate,实现流式重采样
- play.go: WAV/MP3 播放自动重采样
- loop.go: BGM 循环播放支持重采样

测试:
- 所有单元测试通过(6/6)
- 支持采样率自动转换(如 16000 Hz → 44100 Hz)

依赖:
- github.com/zeozeozeo/gomplerate v0.0.0
This commit is contained in:
2026-04-08 19:39:58 +08:00
parent baa32fedc3
commit 4ddecb7c30
6 changed files with 174 additions and 21 deletions

View File

@@ -33,7 +33,21 @@ func PlayMP3Loop(r io.ReadCloser) (*oto.Player, func() error, error) {
return nil, func() error { return nil }, err
}
player := otoCtx.NewPlayer(dec)
// 获取采样率信息
sampleRate := int(dec.SampleRate())
targetRate := UniversalSampleRate
// 需要重采样
var reader io.Reader = dec
if needsResample(sampleRate, targetRate) {
resampleReader, err := newResamplingReader(dec, sampleRate, targetRate, 2)
if err != nil {
return nil, func() error { return nil }, err
}
reader = resampleReader
}
player := otoCtx.NewPlayer(reader)
playing := atomic.Bool{}
playing.Store(true)
@@ -48,6 +62,7 @@ func PlayMP3Loop(r io.ReadCloser) (*oto.Player, func() error, error) {
time.Sleep(10 * time.Millisecond)
}
if playing.Load() {
// 重置解码器位置
_, _ = dec.Seek(0, io.SeekStart)
}
}