audio: Block all the players when suspended

This avoid to write 0 bytes when the app is in background. This
should reduce CPU usage.

Updates #931
This commit is contained in:
Hajime Hoshi 2019-09-07 01:59:36 +09:00
parent c982e00bb0
commit dbb8a5e873

View File

@ -62,12 +62,12 @@ type Context struct {
sampleRate int sampleRate int
err error err error
suspended bool
ready bool ready bool
players map[*playerImpl]struct{} players map[*playerImpl]struct{}
m sync.Mutex m sync.Mutex
semaphore chan struct{}
} }
var ( var (
@ -99,19 +99,16 @@ func NewContext(sampleRate int) (*Context, error) {
c: newContext(sampleRate), c: newContext(sampleRate),
players: map[*playerImpl]struct{}{}, players: map[*playerImpl]struct{}{},
inited: make(chan struct{}), inited: make(chan struct{}),
semaphore: make(chan struct{}, 1),
} }
theContext = c theContext = c
h := getHook() h := getHook()
h.OnSuspendAudio(func() { h.OnSuspendAudio(func() {
c.m.Lock() c.semaphore <- struct{}{}
c.suspended = true
c.m.Unlock()
}) })
h.OnResumeAudio(func() { h.OnResumeAudio(func() {
c.m.Lock() <-c.semaphore
c.suspended = false
c.m.Unlock()
}) })
h.AppendHookOnBeforeUpdate(func() error { h.AppendHookOnBeforeUpdate(func() error {
@ -141,13 +138,6 @@ func CurrentContext() *Context {
return c return c
} }
func (c *Context) playable() bool {
c.m.Lock()
s := c.suspended
c.m.Unlock()
return !s
}
func (c *Context) hasError() bool { func (c *Context) hasError() bool {
c.m.Lock() c.m.Lock()
r := c.err != nil r := c.err != nil
@ -447,11 +437,10 @@ func (p *playerImpl) read() ([]byte, bool) {
const bufSize = 2048 const bufSize = 2048
if !p.context.playable() { p.context.semaphore <- struct{}{}
// Fill zero values, or the driver can block forever as trying to proceed. defer func() {
buf := make([]byte, bufSize) <-p.context.semaphore
return buf, true }()
}
newBuf := make([]byte, bufSize-len(p.buf)) newBuf := make([]byte, bufSize-len(p.buf))
n, err := p.src.Read(newBuf) n, err := p.src.Read(newBuf)