Skip to content

Commit

Permalink
Add speaker.PlayAndWait
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkKremer committed Jan 7, 2024
1 parent f2cc5a2 commit aced228
Showing 1 changed file with 25 additions and 1 deletion.
26 changes: 25 additions & 1 deletion speaker/speaker.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package speaker
import (
"io"
"sync"
"time"

"github.com/ebitengine/oto/v3"
"github.com/pkg/errors"
Expand All @@ -21,6 +22,8 @@ var (
mixer beep.Mixer
context *oto.Context
player *oto.Player

bufferDuration time.Duration
)

// Init initializes audio playback through speaker. Must be called before using this package.
Expand All @@ -45,7 +48,7 @@ func Init(sampleRate beep.SampleRate, bufferSize int) error {

var err error
var readyChan chan struct{}
context, readyChan, err := oto.NewContext(&oto.NewContextOptions{
context, readyChan, err = oto.NewContext(&oto.NewContextOptions{
SampleRate: int(sampleRate),
ChannelCount: channelCount,
Format: otoFormat,
Expand All @@ -60,6 +63,8 @@ func Init(sampleRate beep.SampleRate, bufferSize int) error {
player.SetBufferSize(playerBufferSize * bytesPerSample)
player.Play()

bufferDuration = sampleRate.D(bufferSize)

return nil
}

Expand Down Expand Up @@ -95,6 +100,25 @@ func Play(s ...beep.Streamer) {
mu.Unlock()
}

// PlayAndWait plays all provided Streamers through the speaker and waits until they have all finished playing.
func PlayAndWait(s ...beep.Streamer) {
mu.Lock()
var wg sync.WaitGroup
wg.Add(len(s))
for _, e := range s {
mixer.Add(beep.Seq(e, beep.Callback(func() {
wg.Done()
})))
}
mu.Unlock()

// Wait for the streamers to drain.
wg.Wait()

// Wait the expected time it takes for the samples to reach the driver.
time.Sleep(bufferDuration)
}

// Clear removes all currently playing Streamers from the speaker.
// Previously buffered samples may still be played.
func Clear() {
Expand Down

0 comments on commit aced228

Please sign in to comment.