mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
audio/internal/readerdriver: Bug fix: ReadFull could get stuck
If the source io.Reader's implementation is not good (e.g., Read returns 0 if the buffer size is not multiples of 4), io.ReadFull gets stuck forever. Instead, use reguler Read with a decent amount of bytes buffer. Closes #1599
This commit is contained in:
parent
5b96439fed
commit
e650e71d8c
@ -96,6 +96,7 @@ type playerImpl struct {
|
|||||||
state playerState
|
state playerState
|
||||||
gain js.Value
|
gain js.Value
|
||||||
err error
|
err error
|
||||||
|
buf []byte
|
||||||
|
|
||||||
nextPos float64
|
nextPos float64
|
||||||
bufferSourceNodes []js.Value
|
bufferSourceNodes []js.Value
|
||||||
@ -176,20 +177,38 @@ func (p *playerImpl) appendBuffer(this js.Value, args []js.Value) interface{} {
|
|||||||
p.nextPos = c + 1.0/60.0
|
p.nextPos = c + 1.0/60.0
|
||||||
}
|
}
|
||||||
|
|
||||||
bs := make([]byte, p.context.oneBufferSize())
|
tmp := make([]byte, 4096)
|
||||||
n, err := io.ReadFull(p.src, bs)
|
need := p.context.oneBufferSize()
|
||||||
if err != nil {
|
bs := make([]byte, 0, need)
|
||||||
if err != io.EOF && err != io.ErrUnexpectedEOF {
|
for need > 0 {
|
||||||
|
if len(p.buf) > 0 {
|
||||||
|
n := len(p.buf)
|
||||||
|
if n > need {
|
||||||
|
n = need
|
||||||
|
}
|
||||||
|
bs = append(bs, p.buf[:n]...)
|
||||||
|
p.buf = p.buf[n:]
|
||||||
|
need -= n
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
n, err := p.src.Read(tmp)
|
||||||
|
if err != nil && err != io.EOF {
|
||||||
p.err = err
|
p.err = err
|
||||||
p.Pause()
|
p.Pause()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
p.eof = true
|
if n > need {
|
||||||
|
p.buf = append(p.buf, tmp[need:]...)
|
||||||
|
n = need
|
||||||
|
}
|
||||||
|
bs = append(bs, tmp[:n]...)
|
||||||
|
need -= n
|
||||||
|
if err == io.EOF {
|
||||||
|
p.eof = true
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if n == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
bs = bs[:n]
|
|
||||||
l, r := toLR(bs)
|
l, r := toLR(bs)
|
||||||
tl, tr := float32SliceToTypedArray(l), float32SliceToTypedArray(r)
|
tl, tr := float32SliceToTypedArray(l), float32SliceToTypedArray(r)
|
||||||
|
|
||||||
@ -234,6 +253,7 @@ func (p *playerImpl) Reset() {
|
|||||||
|
|
||||||
p.Pause()
|
p.Pause()
|
||||||
p.eof = false
|
p.eof = false
|
||||||
|
p.buf = p.buf[:0]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *playerImpl) Volume() float64 {
|
func (p *playerImpl) Volume() float64 {
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
package audio
|
package audio
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
@ -243,7 +242,8 @@ func newTimeStream(r io.Reader, sampleRate int, maxBufferSize int) (*timeStream,
|
|||||||
|
|
||||||
func (s *timeStream) Unread(n int) {
|
func (s *timeStream) Unread(n int) {
|
||||||
if s.unread+n > len(s.buf) {
|
if s.unread+n > len(s.buf) {
|
||||||
panic(fmt.Sprintf("audio: too much unreading: %d, the buffer size: %d, unreading position: %d", n, len(s.buf), s.unread))
|
// This should not happen usually, but the player's UnplayedBufferSize can include some errors.
|
||||||
|
n = len(s.buf) - s.unread
|
||||||
}
|
}
|
||||||
s.unread += n
|
s.unread += n
|
||||||
s.pos -= int64(n)
|
s.pos -= int64(n)
|
||||||
|
Loading…
Reference in New Issue
Block a user