PortAudio:默认帧/缓冲区播放延迟
PortAudio: Playback lag at default frames-per-buffer
我正在尝试使用 PortAudio 在 Go 中异步播放音频。据我所知,PortAudio 处理它自己的线程,所以我不需要使用任何 Go 的内置并发性东西。我正在使用 libsndfile 加载文件(也是 Go 绑定)。这是我的代码:
type Track struct {
stream *portaudio.Stream
playhead int
buffer []int32
}
func LoadTrackFilesize(filename string, loop bool, bytes int) *Track {
// Load file
var info sndfile.Info
soundFile, err := sndfile.Open(filename, sndfile.Read, &info)
if err != nil {
fmt.Printf("Could not open file: %s\n", filename)
panic(err)
}
buffer := make([]int32, bytes)
numRead, err := soundFile.ReadItems(buffer)
if err != nil {
fmt.Printf("Error reading from file: %s\n", filename)
panic(err)
}
defer soundFile.Close()
// Create track
track := Track{
buffer: buffer[:numRead],
}
// Create stream
stream, err := portaudio.OpenDefaultStream(
0, 2, float64(44100), portaudio.FramesPerBufferUnspecified, track.playCallback,
)
if err != nil {
fmt.Printf("Couldn't get stream for file: %s\n", filename)
}
track.stream = stream
return &track
}
func (t *Track) playCallback(out []int32) {
for i := range out {
out[i] = t.buffer[(t.playhead+i)%len(t.buffer)]
}
t.playhead += len(out) % len(t.buffer)
}
func (t *Track) Play() {
t.stream.Start()
}
使用这些功能,在初始化 PortAudio 和所有其他功能后,播放我提供的音轨 - 只是。它 非常 滞后,并减慢了我的应用程序的其余部分(游戏循环)。
但是,如果我将每个缓冲区的帧数从 FramesPerBufferUnspecified
更改为较高值,例如 1024,音频播放效果很好,不会干扰我的应用程序的其余部分。
这是为什么? PortAudio 文档建议使用未指定的值 'choose a value for optimum latency',但我绝对没有看到。
此外,当播放这个非常高的值时,我注意到音频中有一些微小的人工制品 - 很小的 'popping' 噪音。
我的回调函数或其他任何问题是否有问题,可能会导致其中一个或两个问题?
我正在使用 OSX 10.10.5,Go 1.3.3 以及来自 Homebrew 的 libsndfile 和 portaudio。
谢谢。
移至对答案的评论:
始终使用最新版本的 Go 进行测试。
此外,@Joel 发现您需要使用 float32
而不是 int32
。
我正在尝试使用 PortAudio 在 Go 中异步播放音频。据我所知,PortAudio 处理它自己的线程,所以我不需要使用任何 Go 的内置并发性东西。我正在使用 libsndfile 加载文件(也是 Go 绑定)。这是我的代码:
type Track struct {
stream *portaudio.Stream
playhead int
buffer []int32
}
func LoadTrackFilesize(filename string, loop bool, bytes int) *Track {
// Load file
var info sndfile.Info
soundFile, err := sndfile.Open(filename, sndfile.Read, &info)
if err != nil {
fmt.Printf("Could not open file: %s\n", filename)
panic(err)
}
buffer := make([]int32, bytes)
numRead, err := soundFile.ReadItems(buffer)
if err != nil {
fmt.Printf("Error reading from file: %s\n", filename)
panic(err)
}
defer soundFile.Close()
// Create track
track := Track{
buffer: buffer[:numRead],
}
// Create stream
stream, err := portaudio.OpenDefaultStream(
0, 2, float64(44100), portaudio.FramesPerBufferUnspecified, track.playCallback,
)
if err != nil {
fmt.Printf("Couldn't get stream for file: %s\n", filename)
}
track.stream = stream
return &track
}
func (t *Track) playCallback(out []int32) {
for i := range out {
out[i] = t.buffer[(t.playhead+i)%len(t.buffer)]
}
t.playhead += len(out) % len(t.buffer)
}
func (t *Track) Play() {
t.stream.Start()
}
使用这些功能,在初始化 PortAudio 和所有其他功能后,播放我提供的音轨 - 只是。它 非常 滞后,并减慢了我的应用程序的其余部分(游戏循环)。
但是,如果我将每个缓冲区的帧数从 FramesPerBufferUnspecified
更改为较高值,例如 1024,音频播放效果很好,不会干扰我的应用程序的其余部分。
这是为什么? PortAudio 文档建议使用未指定的值 'choose a value for optimum latency',但我绝对没有看到。
此外,当播放这个非常高的值时,我注意到音频中有一些微小的人工制品 - 很小的 'popping' 噪音。
我的回调函数或其他任何问题是否有问题,可能会导致其中一个或两个问题?
我正在使用 OSX 10.10.5,Go 1.3.3 以及来自 Homebrew 的 libsndfile 和 portaudio。
谢谢。
移至对答案的评论:
始终使用最新版本的 Go 进行测试。
此外,@Joel 发现您需要使用 float32
而不是 int32
。