mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
audio: Consider the state of the player's starting and seeking
Before this change, if a player's buffer was not enough for reading, 0 value were used and this caused noises. The reading size should be aligned with all the players. Just after a player just starts playing or seeking, the buffer is empty but other players should not wait for the player read since decoding might take some time. To summerize, this change aligns the read buffer sizes but use zero values only when the player just starts or seeks.
This commit is contained in:
parent
91958d24ef
commit
2fee7a6fe5
@ -74,6 +74,18 @@ func (p *players) Read(b []byte) (int, error) {
|
|||||||
l := len(b)
|
l := len(b)
|
||||||
l &= mask
|
l &= mask
|
||||||
|
|
||||||
|
for player := range p.players {
|
||||||
|
if player.isJustAfterStartedOrSeeked() {
|
||||||
|
println("oh")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
s := player.bufferSizeInBytes()
|
||||||
|
if l > s {
|
||||||
|
l = s
|
||||||
|
l &= mask
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
b16s := [][]int16{}
|
b16s := [][]int16{}
|
||||||
for player := range p.players {
|
for player := range p.players {
|
||||||
buf, err := player.bufferToInt16(l)
|
buf, err := player.bufferToInt16(l)
|
||||||
@ -82,6 +94,7 @@ func (p *players) Read(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
b16s = append(b16s, buf)
|
b16s = append(b16s, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < l/2; i++ {
|
for i := 0; i < l/2; i++ {
|
||||||
x := 0
|
x := 0
|
||||||
for _, b16 := range b16s {
|
for _, b16 := range b16s {
|
||||||
@ -349,7 +362,7 @@ func NewPlayer(context *Context, src io.ReadCloser) (*Player, error) {
|
|||||||
players: context.players,
|
players: context.players,
|
||||||
src: src,
|
src: src,
|
||||||
sampleRate: context.sampleRate,
|
sampleRate: context.sampleRate,
|
||||||
buf: []byte{},
|
buf: nil,
|
||||||
volume: 1,
|
volume: 1,
|
||||||
closeCh: make(chan struct{}),
|
closeCh: make(chan struct{}),
|
||||||
closedCh: make(chan struct{}),
|
closedCh: make(chan struct{}),
|
||||||
@ -526,13 +539,15 @@ func (p *Player) readLoop() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
lengthInBytes := len(buf) * 2
|
if p.isJustAfterStartedOrSeekedImpl() {
|
||||||
l := lengthInBytes
|
// Return zero values.
|
||||||
|
|
||||||
if len(p.buf) < lengthInBytes && !p.srcEOF {
|
|
||||||
p.proceededCh <- proceededValues{buf, nil}
|
p.proceededCh <- proceededValues{buf, nil}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lengthInBytes := len(buf) * 2
|
||||||
|
l := lengthInBytes
|
||||||
|
|
||||||
if l > len(p.buf) {
|
if l > len(p.buf) {
|
||||||
l = len(p.buf)
|
l = len(p.buf)
|
||||||
}
|
}
|
||||||
@ -543,7 +558,7 @@ func (p *Player) readLoop() {
|
|||||||
p.pos += int64(l)
|
p.pos += int64(l)
|
||||||
p.buf = p.buf[l:]
|
p.buf = p.buf[l:]
|
||||||
|
|
||||||
p.proceededCh <- proceededValues{buf, nil}
|
p.proceededCh <- proceededValues{buf[:l/2], nil}
|
||||||
|
|
||||||
case f := <-p.syncCh:
|
case f := <-p.syncCh:
|
||||||
f()
|
f()
|
||||||
@ -566,6 +581,28 @@ func (p *Player) sync(f func()) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Player) isJustAfterStartedOrSeeked() bool {
|
||||||
|
r := false
|
||||||
|
p.sync(func() {
|
||||||
|
r = p.isJustAfterStartedOrSeekedImpl()
|
||||||
|
})
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) isJustAfterStartedOrSeekedImpl() bool {
|
||||||
|
// When p.buf is nil, the player just starts playing or seeking.
|
||||||
|
// Note that this is different from len(p.buf) == 0 && p.buf != nil.
|
||||||
|
return p.buf == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) bufferSizeInBytes() int {
|
||||||
|
s := 0
|
||||||
|
p.sync(func() {
|
||||||
|
s = len(p.buf)
|
||||||
|
})
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Player) eof() bool {
|
func (p *Player) eof() bool {
|
||||||
r := false
|
r := false
|
||||||
p.sync(func() {
|
p.sync(func() {
|
||||||
|
Loading…
Reference in New Issue
Block a user