audio: Bug fix: isPlaying must consider two buffers in JS

This commit is contained in:
Hajime Hoshi 2016-02-09 23:49:33 +09:00
parent 2ba25b1a14
commit c5de32297f
2 changed files with 18 additions and 22 deletions

View File

@ -50,8 +50,7 @@ func withChannels(f func()) {
f() f()
} }
func channelAt(i int) *channel { func emptyChannel() *channel {
if i == -1 {
for i, _ := range channels { for i, _ := range channels {
if !isPlaying(i) { if !isPlaying(i) {
return channels[i] return channels[i]
@ -59,11 +58,6 @@ func channelAt(i int) *channel {
} }
return nil return nil
} }
if !isPlaying(i) {
return channels[i]
}
return nil
}
func Tick() { func Tick() {
tick() tick()
@ -77,7 +71,7 @@ func Queue(data []byte) bool {
result = false result = false
return return
} }
ch := channelAt(-1) ch := emptyChannel()
if ch == nil { if ch == nil {
result = false result = false
return return

View File

@ -20,12 +20,7 @@ import (
"github.com/gopherjs/gopherjs/js" "github.com/gopherjs/gopherjs/js"
) )
// Keep this as global so as not to be destroyed by GC. var context *js.Object
var (
nodes = []*js.Object{}
dummies = []*js.Object{} // Dummy source nodes for iOS.
context *js.Object
)
type audioProcessor struct { type audioProcessor struct {
channel int channel int
@ -63,22 +58,29 @@ func (a *audioProcessor) playChunk(buf []byte) {
s := context.Call("createBufferSource") s := context.Call("createBufferSource")
s.Set("buffer", b) s.Set("buffer", b)
s.Call("connect", context.Get("destination")) s.Call("connect", context.Get("destination"))
c := context.Get("currentTime").Float()
if a.position < c {
a.position = c
}
s.Call("start", a.position) s.Call("start", a.position)
a.position += float64(len(il)) / float64(a.sampleRate) a.position += float64(len(il)) / float64(a.sampleRate)
} }
func isPlaying(channel int) bool { func isPlaying(channel int) bool {
ch := channels[channel]
if 0 < len(ch.buffer) {
return true
}
a := audioProcessors[channel]
c := context.Get("currentTime").Float() c := context.Get("currentTime").Float()
return c < audioProcessors[channel].position return c < a.position
} }
func tick() { func tick() {
const bufferSize = 1024 const bufferSize = 1024
c := context.Get("currentTime").Float()
for _, a := range audioProcessors { for _, a := range audioProcessors {
if a.position < c {
a.position = c
}
// TODO: 4 is a magic number
a.playChunk(loadChannelBuffer(a.channel, bufferSize*4)) a.playChunk(loadChannelBuffer(a.channel, bufferSize*4))
} }
} }