mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-13 12:32:05 +01:00
audio: Remove player's mutex
This commit is contained in:
parent
637ed0d965
commit
19ca74e86b
@ -338,8 +338,7 @@ type Player struct {
|
|||||||
seekedCh chan error
|
seekedCh chan error
|
||||||
proceedCh chan []int16
|
proceedCh chan []int16
|
||||||
proceededCh chan proceededValues
|
proceededCh chan proceededValues
|
||||||
|
syncCh chan func()
|
||||||
m sync.RWMutex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type seekArgs struct {
|
type seekArgs struct {
|
||||||
@ -379,6 +378,7 @@ func NewPlayer(context *Context, src ReadSeekCloser) (*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()),
|
||||||
}
|
}
|
||||||
// Get the current position of the source.
|
// Get the current position of the source.
|
||||||
pos, err := p.src.Seek(0, io.SeekCurrent)
|
pos, err := p.src.Seek(0, io.SeekCurrent)
|
||||||
@ -453,6 +453,8 @@ func (p *Player) readLoop() {
|
|||||||
defer func() {
|
defer func() {
|
||||||
// Note: the error is ignored
|
// Note: the error is ignored
|
||||||
p.src.Close()
|
p.src.Close()
|
||||||
|
// Receiving from a closed channel returns quickly
|
||||||
|
// i.e. `case <-p.readLoopEndedCh:` can check if this loops is ended.
|
||||||
close(p.readLoopEndedCh)
|
close(p.readLoopEndedCh)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -466,47 +468,36 @@ func (p *Player) readLoop() {
|
|||||||
|
|
||||||
case s := <-p.seekCh:
|
case s := <-p.seekCh:
|
||||||
pos, err := p.src.Seek(s.offset, s.whence)
|
pos, err := p.src.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
|
||||||
t = time.After(time.Millisecond)
|
t = time.After(time.Millisecond)
|
||||||
break
|
break
|
||||||
|
|
||||||
case <-t:
|
case <-t:
|
||||||
p.m.Lock()
|
|
||||||
if len(p.buf) >= 4096*16 {
|
if len(p.buf) >= 4096*16 {
|
||||||
t = time.After(10 * time.Millisecond)
|
t = time.After(10 * time.Millisecond)
|
||||||
p.m.Unlock()
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
p.m.Unlock()
|
|
||||||
|
|
||||||
buf := make([]byte, 4096)
|
buf := make([]byte, 4096)
|
||||||
n, err := p.src.Read(buf)
|
n, err := p.src.Read(buf)
|
||||||
|
|
||||||
p.m.Lock()
|
|
||||||
p.buf = append(p.buf, buf[:n]...)
|
p.buf = append(p.buf, buf[:n]...)
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
p.srcEOF = true
|
p.srcEOF = true
|
||||||
}
|
}
|
||||||
if p.srcEOF && len(p.buf) == 0 {
|
if p.srcEOF && len(p.buf) == 0 {
|
||||||
t = nil
|
t = nil
|
||||||
p.m.Unlock()
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
readErr = err
|
readErr = err
|
||||||
t = nil
|
t = nil
|
||||||
p.m.Unlock()
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
t = time.After(time.Millisecond)
|
t = time.After(time.Millisecond)
|
||||||
p.m.Unlock()
|
|
||||||
|
|
||||||
case buf := <-p.proceedCh:
|
case buf := <-p.proceedCh:
|
||||||
if readErr != nil {
|
if readErr != nil {
|
||||||
@ -517,12 +508,9 @@ func (p *Player) readLoop() {
|
|||||||
lengthInBytes := len(buf) * 2
|
lengthInBytes := len(buf) * 2
|
||||||
l := lengthInBytes
|
l := lengthInBytes
|
||||||
|
|
||||||
p.m.Lock()
|
|
||||||
|
|
||||||
// Buffer size needs to be much more than the actual required length
|
// Buffer size needs to be much more than the actual required length
|
||||||
// so that noise caused by empty buffer can be avoided.
|
// so that noise caused by empty buffer can be avoided.
|
||||||
if len(p.buf) < lengthInBytes*4 && !p.srcEOF {
|
if len(p.buf) < lengthInBytes*4 && !p.srcEOF {
|
||||||
p.m.Unlock()
|
|
||||||
p.proceededCh <- proceededValues{buf, nil}
|
p.proceededCh <- proceededValues{buf, nil}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -536,16 +524,34 @@ func (p *Player) 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, nil}
|
p.proceededCh <- proceededValues{buf, nil}
|
||||||
|
|
||||||
|
case f := <-p.syncCh:
|
||||||
|
f()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Player) 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 *Player) eof() bool {
|
func (p *Player) eof() bool {
|
||||||
p.m.RLock()
|
r := false
|
||||||
r := p.srcEOF && len(p.buf) == 0
|
p.sync(func() {
|
||||||
p.m.RUnlock()
|
r = p.srcEOF && len(p.buf) == 0
|
||||||
|
})
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -585,18 +591,19 @@ func (p *Player) Pause() error {
|
|||||||
|
|
||||||
// Current returns the current position.
|
// Current returns the current position.
|
||||||
func (p *Player) Current() time.Duration {
|
func (p *Player) Current() time.Duration {
|
||||||
p.m.RLock()
|
sample := int64(0)
|
||||||
sample := p.pos / bytesPerSample / channelNum
|
p.sync(func() {
|
||||||
p.m.RUnlock()
|
sample = p.pos / bytesPerSample / channelNum
|
||||||
|
})
|
||||||
return time.Duration(sample) * time.Second / time.Duration(p.sampleRate)
|
return time.Duration(sample) * time.Second / time.Duration(p.sampleRate)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Volume returns the current volume of this player [0-1].
|
// Volume returns the current volume of this player [0-1].
|
||||||
func (p *Player) Volume() float64 {
|
func (p *Player) Volume() float64 {
|
||||||
p.m.RLock()
|
v := 0.0
|
||||||
v := p.volume
|
p.sync(func() {
|
||||||
p.m.RUnlock()
|
v = p.volume
|
||||||
|
})
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,7 +615,7 @@ func (p *Player) SetVolume(volume float64) {
|
|||||||
panic("audio: volume must be in between 0 and 1")
|
panic("audio: volume must be in between 0 and 1")
|
||||||
}
|
}
|
||||||
|
|
||||||
p.m.Lock()
|
p.sync(func() {
|
||||||
p.volume = volume
|
p.volume = volume
|
||||||
p.m.Unlock()
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user