audio: Remove (*playerImpl).sync and use mutex instead

This is a preparation to work syncing wihtout the read-loop.
This commit is contained in:
Hajime Hoshi 2019-04-28 00:53:46 +09:00
parent 4ab97ad250
commit 4f831de008

View File

@ -238,9 +238,10 @@ type playerImpl struct {
seekedCh chan error seekedCh chan error
proceedCh chan []int16 proceedCh chan []int16
proceededCh chan proceededValues proceededCh chan proceededValues
syncCh chan func()
finalized bool finalized bool
m sync.Mutex
} }
type seekArgs struct { type seekArgs struct {
@ -286,7 +287,6 @@ func NewPlayer(context *Context, src io.ReadCloser) (*Player, error) {
seekedCh: make(chan error), seekedCh: make(chan error),
proceedCh: make(chan []int16), proceedCh: make(chan []int16),
proceededCh: make(chan proceededValues), proceededCh: make(chan proceededValues),
syncCh: make(chan func()),
}, },
} }
if seeker, ok := p.p.src.(io.Seeker); ok { if seeker, ok := p.p.src.(io.Seeker); ok {
@ -334,16 +334,15 @@ func (p *Player) finalize() {
} }
func (p *playerImpl) setFinalized(finalized bool) { func (p *playerImpl) setFinalized(finalized bool) {
p.sync(func() { p.m.Lock()
p.finalized = finalized p.finalized = finalized
}) p.m.Unlock()
} }
func (p *playerImpl) isFinalized() bool { func (p *playerImpl) isFinalized() bool {
b := false p.m.Lock()
p.sync(func() { b := p.finalized
b = p.finalized p.m.Unlock()
})
return b return b
} }
@ -419,9 +418,13 @@ func (p *playerImpl) readLoop() {
panic("audio: the source must be io.Seeker when seeking") panic("audio: the source must be io.Seeker when seeking")
} }
pos, err := seeker.Seek(s.offset, s.whence) pos, err := seeker.Seek(s.offset, s.whence)
p.m.Lock()
p.buf = nil p.buf = nil
p.pos = pos p.pos = pos
p.srcEOF = false p.srcEOF = false
p.m.Unlock()
p.seekedCh <- err p.seekedCh <- err
if timer != nil { if timer != nil {
timer.Stop() timer.Stop()
@ -431,12 +434,14 @@ func (p *playerImpl) readLoop() {
case <-timerCh: case <-timerCh:
// If the buffer has 1 second, that's enough. // If the buffer has 1 second, that's enough.
p.m.Lock()
if len(p.buf) >= p.sampleRate*bytesPerSample { if len(p.buf) >= p.sampleRate*bytesPerSample {
if timer != nil { if timer != nil {
timer.Stop() timer.Stop()
} }
timer = time.NewTimer(100 * time.Millisecond) timer = time.NewTimer(100 * time.Millisecond)
timerCh = timer.C timerCh = timer.C
p.m.Unlock()
break break
} }
@ -462,8 +467,11 @@ func (p *playerImpl) readLoop() {
} }
timer = nil timer = nil
timerCh = nil timerCh = nil
p.m.Unlock()
break break
} }
p.m.Unlock()
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
readErr = err readErr = err
if timer != nil { if timer != nil {
@ -489,9 +497,11 @@ func (p *playerImpl) readLoop() {
return return
} }
p.m.Lock()
if p.shouldSkipImpl() { if p.shouldSkipImpl() {
// Return zero values. // Return zero values.
p.proceededCh <- proceededValues{buf, nil} p.proceededCh <- proceededValues{buf, nil}
p.m.Unlock()
break break
} }
@ -507,35 +517,17 @@ func (p *playerImpl) readLoop() {
} }
p.pos += int64(l) p.pos += int64(l)
p.buf = p.buf[l:] p.buf = p.buf[l:]
p.m.Unlock()
p.proceededCh <- proceededValues{buf[:l/2], nil} p.proceededCh <- proceededValues{buf[:l/2], nil}
case f := <-p.syncCh:
f()
} }
} }
} }
func (p *playerImpl) sync(f func()) bool {
ch := make(chan struct{})
ff := func() {
f()
close(ch)
}
select {
case p.syncCh <- ff:
<-ch
return true
case <-p.readLoopEndedCh:
return false
}
}
func (p *playerImpl) shouldSkip() bool { func (p *playerImpl) shouldSkip() bool {
r := false p.m.Lock()
p.sync(func() { r := p.shouldSkipImpl()
r = p.shouldSkipImpl() p.m.Unlock()
})
return r return r
} }
@ -552,18 +544,16 @@ func (p *playerImpl) shouldSkipImpl() bool {
} }
func (p *playerImpl) bufferSizeInBytes() int { func (p *playerImpl) bufferSizeInBytes() int {
s := 0 p.m.Lock()
p.sync(func() { s := len(p.buf)
s = len(p.buf) p.m.Unlock()
})
return s return s
} }
func (p *playerImpl) eof() bool { func (p *playerImpl) eof() bool {
r := false p.m.Lock()
p.sync(func() { r := p.eofImpl()
r = p.eofImpl() p.m.Unlock()
})
return r return r
} }
@ -637,10 +627,9 @@ func (p *Player) Current() time.Duration {
} }
func (p *playerImpl) Current() time.Duration { func (p *playerImpl) Current() time.Duration {
sample := int64(0) p.m.Lock()
p.sync(func() { sample := p.pos / bytesPerSample
sample = p.pos / bytesPerSample p.m.Unlock()
})
return time.Duration(sample) * time.Second / time.Duration(p.sampleRate) return time.Duration(sample) * time.Second / time.Duration(p.sampleRate)
} }
@ -650,10 +639,9 @@ func (p *Player) Volume() float64 {
} }
func (p *playerImpl) Volume() float64 { func (p *playerImpl) Volume() float64 {
v := 0.0 p.m.Lock()
p.sync(func() { v := p.volume
v = p.volume p.m.Unlock()
})
return v return v
} }
@ -669,7 +657,7 @@ func (p *playerImpl) SetVolume(volume float64) {
panic("audio: volume must be in between 0 and 1") panic("audio: volume must be in between 0 and 1")
} }
p.sync(func() { p.m.Lock()
p.volume = volume p.volume = volume
}) p.m.Unlock()
} }