mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-26 03:38:55 +01:00
audio: Bug fix: Fill empty data even when audio is suspended
When writing is stopped on Oto's players, unexpected delaying happens. The ideal solution is to have APIs to suspend and resume Oto's player, but this is not easy. For a temporary solution, write zero values on the players when audio is suspended. Fixes #975
This commit is contained in:
parent
ddba7f0ee0
commit
529dddda53
@ -63,11 +63,11 @@ type Context struct {
|
|||||||
sampleRate int
|
sampleRate int
|
||||||
err error
|
err error
|
||||||
ready bool
|
ready bool
|
||||||
|
suspended bool
|
||||||
|
|
||||||
players map[*playerImpl]struct{}
|
players map[*playerImpl]struct{}
|
||||||
|
|
||||||
m sync.Mutex
|
m sync.Mutex
|
||||||
semaphore chan struct{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -75,6 +75,8 @@ var (
|
|||||||
theContextLock sync.Mutex
|
theContextLock sync.Mutex
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var emptyBytes = make([]byte, 256)
|
||||||
|
|
||||||
// NewContext creates a new audio context with the given sample rate.
|
// NewContext creates a new audio context with the given sample rate.
|
||||||
//
|
//
|
||||||
// The sample rate is also used for decoding MP3 with audio/mp3 package
|
// The sample rate is also used for decoding MP3 with audio/mp3 package
|
||||||
@ -99,16 +101,19 @@ 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.semaphore <- struct{}{}
|
c.m.Lock()
|
||||||
|
c.suspended = true
|
||||||
|
c.m.Unlock()
|
||||||
})
|
})
|
||||||
h.OnResumeAudio(func() {
|
h.OnResumeAudio(func() {
|
||||||
<-c.semaphore
|
c.m.Lock()
|
||||||
|
c.suspended = false
|
||||||
|
c.m.Unlock()
|
||||||
})
|
})
|
||||||
|
|
||||||
h.AppendHookOnBeforeUpdate(func() error {
|
h.AppendHookOnBeforeUpdate(func() error {
|
||||||
@ -455,10 +460,14 @@ func (p *playerImpl) read() ([]byte, bool) {
|
|||||||
|
|
||||||
const bufSize = 2048
|
const bufSize = 2048
|
||||||
|
|
||||||
p.context.semaphore <- struct{}{}
|
// If audio is suspended, fill zero values not to cause delay (#975).
|
||||||
defer func() {
|
// TODO: Oto's players should be able to be suspended and resumed.
|
||||||
<-p.context.semaphore
|
p.context.m.Lock()
|
||||||
}()
|
s := p.context.suspended
|
||||||
|
p.context.m.Unlock()
|
||||||
|
if s {
|
||||||
|
return emptyBytes, 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)
|
||||||
|
Loading…
Reference in New Issue
Block a user