audio: Simplify read/write logic

This commit is contained in:
Hajime Hoshi 2017-12-24 00:23:57 +09:00
parent 00d8d61795
commit 7ce87a6c82

View File

@ -155,9 +155,6 @@ type Context struct {
initedCh chan struct{} initedCh chan struct{}
pingCount int pingCount int
sampleRate int sampleRate int
frames int64
framesReadOnly int64
writtenBytes int64
m sync.Mutex m sync.Mutex
} }
@ -252,6 +249,9 @@ func (c *Context) loop() {
close(c.initedCh) close(c.initedCh)
bytesPerFrame := c.sampleRate * bytesPerSample * channelNum / clock.FPS
written := int64(0)
prevWritten := int64(0)
for { for {
c.m.Lock() c.m.Lock()
if c.pingCount == 0 { if c.pingCount == 0 {
@ -261,21 +261,26 @@ func (c *Context) loop() {
} }
c.pingCount-- c.pingCount--
c.m.Unlock() c.m.Unlock()
c.frames++
buf := make([]byte, 4096)
n, err := c.players.Read(buf)
if err != nil {
audiobinding.SetError(err)
return
}
if _, err = p.Write(buf[:n]); err != nil {
audiobinding.SetError(err)
return
}
written += int64(n)
fs := written/int64(bytesPerFrame) - prevWritten/int64(bytesPerFrame)
for fs > 0 {
clock.ProceedPrimaryTimer() clock.ProceedPrimaryTimer()
bytesPerFrame := c.sampleRate * bytesPerSample * channelNum / clock.FPS fs--
l := (c.frames * int64(bytesPerFrame)) - c.writtenBytes
l &= mask
c.writtenBytes += l
buf := make([]byte, l)
if _, err := io.ReadFull(c.players, buf); err != nil {
audiobinding.SetError(err)
return
}
if _, err = p.Write(buf); err != nil {
audiobinding.SetError(err)
return
} }
prevWritten = written
} }
} }
@ -478,13 +483,13 @@ func (p *Player) readLoop() {
case <-t: case <-t:
// If the buffer has 1 second, that's enough. // If the buffer has 1 second, that's enough.
if len(p.buf) >= p.sampleRate*4 { if len(p.buf) >= p.sampleRate*bytesPerSample*channelNum {
t = time.After(100 * time.Millisecond) t = time.After(100 * time.Millisecond)
break break
} }
// Try to read the buffer for 1/15[s]. // Try to read the buffer for 1/15[s].
l := p.sampleRate * 4 / 15 l := p.sampleRate * bytesPerSample * channelNum / 15
l &= mask l &= mask
buf := make([]byte, l) buf := make([]byte, l)
n, err := p.src.Read(buf) n, err := p.src.Read(buf)
@ -515,7 +520,7 @@ func (p *Player) readLoop() {
// 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*15 && !p.srcEOF { if len(p.buf) < lengthInBytes*8 && !p.srcEOF {
p.proceededCh <- proceededValues{buf, nil} p.proceededCh <- proceededValues{buf, nil}
break break
} }