From 6a2fdc8f38950f02abff5ed3011c0ee9bf6480ff Mon Sep 17 00:00:00 2001 From: Jerry Caligiure Date: Tue, 30 Oct 2018 15:40:51 -0400 Subject: [PATCH] separate oto on its own goroutine --- common/audio.go | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/common/audio.go b/common/audio.go index e088241e..cd0991f6 100644 --- a/common/audio.go +++ b/common/audio.go @@ -31,8 +31,9 @@ type audioEntity struct { type AudioSystem struct { entities []audioEntity - otoPlayer *oto.Player - bufsize int + otoPlayer *oto.Player + bufsize int + audioReadC, audioCloser chan struct{} } // New is called when the AudioSystem is added to the world. @@ -48,11 +49,30 @@ func (a *AudioSystem) New(w *ecs.World) { if err != nil { log.Printf("audio error. Unable to create new OtoPlayer: %v \n\r", err) } + a.audioCloser = make(chan struct{}) runtime.SetFinalizer(a.otoPlayer, func(p *oto.Player) { if err := p.Close(); err != nil { log.Printf("audio error. Unable to close OtoPlayer: %v \n\r", err) } + close(a.audioCloser) }) + // run oto on a separate thread so it doesn't slow down updates + a.audioReadC = make(chan struct{}, 10) + go func() { + for { + select { + case <-a.audioReadC: + buf := make([]byte, a.bufsize) + a.read(buf) + + if _, err := a.otoPlayer.Write(buf); err != nil { + log.Printf("error copying to OtoPlayer: %v \r\n", err) + } + case <-a.audioCloser: + return + } + } + }() masterVolume = 1 } @@ -85,11 +105,9 @@ func (a *AudioSystem) Remove(basic ecs.BasicEntity) { // Update is called once per frame, and updates/plays the players in the AudioSystem func (a *AudioSystem) Update(dt float32) { - buf := make([]byte, a.bufsize) - a.read(buf) - - if _, err := a.otoPlayer.Write(buf); err != nil { - log.Printf("error copying to OtoPlayer: %v \r\n", err) + select { + case a.audioReadC <- struct{}{}: + default: } }