mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 11:18:54 +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
|
||||
err error
|
||||
ready bool
|
||||
suspended bool
|
||||
|
||||
players map[*playerImpl]struct{}
|
||||
|
||||
m sync.Mutex
|
||||
semaphore chan struct{}
|
||||
m sync.Mutex
|
||||
}
|
||||
|
||||
var (
|
||||
@ -75,6 +75,8 @@ var (
|
||||
theContextLock sync.Mutex
|
||||
)
|
||||
|
||||
var emptyBytes = make([]byte, 256)
|
||||
|
||||
// NewContext creates a new audio context with the given sample rate.
|
||||
//
|
||||
// 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),
|
||||
players: map[*playerImpl]struct{}{},
|
||||
inited: make(chan struct{}),
|
||||
semaphore: make(chan struct{}, 1),
|
||||
}
|
||||
theContext = c
|
||||
|
||||
h := getHook()
|
||||
h.OnSuspendAudio(func() {
|
||||
c.semaphore <- struct{}{}
|
||||
c.m.Lock()
|
||||
c.suspended = true
|
||||
c.m.Unlock()
|
||||
})
|
||||
h.OnResumeAudio(func() {
|
||||
<-c.semaphore
|
||||
c.m.Lock()
|
||||
c.suspended = false
|
||||
c.m.Unlock()
|
||||
})
|
||||
|
||||
h.AppendHookOnBeforeUpdate(func() error {
|
||||
@ -455,10 +460,14 @@ func (p *playerImpl) read() ([]byte, bool) {
|
||||
|
||||
const bufSize = 2048
|
||||
|
||||
p.context.semaphore <- struct{}{}
|
||||
defer func() {
|
||||
<-p.context.semaphore
|
||||
}()
|
||||
// If audio is suspended, fill zero values not to cause delay (#975).
|
||||
// TODO: Oto's players should be able to be suspended and resumed.
|
||||
p.context.m.Lock()
|
||||
s := p.context.suspended
|
||||
p.context.m.Unlock()
|
||||
if s {
|
||||
return emptyBytes, true
|
||||
}
|
||||
|
||||
newBuf := make([]byte, bufSize-len(p.buf))
|
||||
n, err := p.src.Read(newBuf)
|
||||
|
Loading…
Reference in New Issue
Block a user