From 3de56070d98331de89158578657f554972ad4d26 Mon Sep 17 00:00:00 2001 From: Mark Kremer Date: Thu, 9 Nov 2023 18:03:06 +0100 Subject: [PATCH] Tweak the speaker's context & player's buffer sizes --- speaker/speaker.go | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/speaker/speaker.go b/speaker/speaker.go index 94d58e9..9c5b080 100644 --- a/speaker/speaker.go +++ b/speaker/speaker.go @@ -2,11 +2,13 @@ package speaker import ( - "github.com/ebitengine/oto/v3" - "github.com/gopxl/beep" - "github.com/pkg/errors" "io" "sync" + + "github.com/ebitengine/oto/v3" + "github.com/pkg/errors" + + "github.com/gopxl/beep" ) const channelCount = 2 @@ -33,13 +35,21 @@ func Init(sampleRate beep.SampleRate, bufferSize int) error { mixer = beep.Mixer{} + // We split the total amount of buffer size between the driver and the player. + // This seems to be a decent ratio on my machine, but it may have different + // results on other OS's because of different underlying implementations. + // Both buffers try to keep themselves filled, so the total buffered + // number of samples should be some number less than bufferSize. + driverBufferSize := bufferSize / 2 + playerBufferSize := bufferSize / 2 + var err error var readyChan chan struct{} context, readyChan, err := oto.NewContext(&oto.NewContextOptions{ SampleRate: int(sampleRate), ChannelCount: channelCount, Format: otoFormat, - BufferSize: 0, // use the default + BufferSize: sampleRate.D(driverBufferSize), }) if err != nil { return errors.Wrap(err, "failed to initialize speaker") @@ -47,7 +57,7 @@ func Init(sampleRate beep.SampleRate, bufferSize int) error { <-readyChan player = context.NewPlayer(newReaderFromStreamer(&mixer)) - player.SetBufferSize(bufferSize * bytesPerSample) + player.SetBufferSize(playerBufferSize * bytesPerSample) player.Play() return nil