audio: Create an independent goroutine for enqueuing

This commit is contained in:
Hajime Hoshi 2016-05-26 02:41:00 +09:00
parent 12d62621e9
commit 644dfcd0fd

View File

@ -182,7 +182,6 @@ import "C"
import ( import (
"errors" "errors"
"sync"
"unsafe" "unsafe"
) )
@ -193,8 +192,8 @@ type Player struct {
audioTrack C.jobject audioTrack C.jobject
buffer []byte buffer []byte
bufferSize int bufferSize int
m sync.Mutex
chErr chan error chErr chan error
chBuffer chan []byte
} }
func NewPlayer(sampleRate, channelNum, bytesPerSample int) (*Player, error) { func NewPlayer(sampleRate, channelNum, bytesPerSample int) (*Player, error) {
@ -204,6 +203,7 @@ func NewPlayer(sampleRate, channelNum, bytesPerSample int) (*Player, error) {
bytesPerSample: bytesPerSample, bytesPerSample: bytesPerSample,
buffer: []byte{}, buffer: []byte{},
chErr: make(chan error), chErr: make(chan error),
chBuffer: make(chan []byte),
} }
if err := runOnJVM(func(vm, env, ctx uintptr) error { if err := runOnJVM(func(vm, env, ctx uintptr) error {
audioTrack := C.jobject(nil) audioTrack := C.jobject(nil)
@ -219,20 +219,8 @@ func NewPlayer(sampleRate, channelNum, bytesPerSample int) (*Player, error) {
}); err != nil { }); err != nil {
return nil, err return nil, err
} }
return p, nil go func() {
} for bufInBytes := range p.chBuffer {
func (p *Player) Proceed(data []byte) error {
select {
case err := <-p.chErr:
return err
default:
}
p.buffer = append(p.buffer, data...)
if len(p.buffer) < p.bufferSize {
return nil
}
bufInBytes := p.buffer[:p.bufferSize]
var bufInShorts []int16 var bufInShorts []int16
if p.bytesPerSample == 2 { if p.bytesPerSample == 2 {
bufInShorts = make([]int16, len(bufInBytes)/2) bufInShorts = make([]int16, len(bufInBytes)/2)
@ -240,10 +228,7 @@ func (p *Player) Proceed(data []byte) error {
bufInShorts[i] = int16(bufInBytes[2*i]) | (int16(bufInBytes[2*i+1]) << 8) bufInShorts[i] = int16(bufInBytes[2*i]) | (int16(bufInBytes[2*i+1]) << 8)
} }
} }
p.buffer = p.buffer[p.bufferSize:]
go func() {
p.m.Lock()
defer p.m.Unlock()
if err := runOnJVM(func(vm, env, ctx uintptr) error { if err := runOnJVM(func(vm, env, ctx uintptr) error {
msg := (*C.char)(nil) msg := (*C.char)(nil)
switch p.bytesPerSample { switch p.bytesPerSample {
@ -262,8 +247,26 @@ func (p *Player) Proceed(data []byte) error {
return nil return nil
}); err != nil { }); err != nil {
p.chErr <- err p.chErr <- err
return
}
} }
}() }()
return p, nil
}
func (p *Player) Proceed(data []byte) error {
select {
case err := <-p.chErr:
return err
default:
}
p.buffer = append(p.buffer, data...)
if len(p.buffer) < p.bufferSize {
return nil
}
buf := p.buffer[:p.bufferSize]
p.chBuffer <- buf
p.buffer = p.buffer[p.bufferSize:]
return nil return nil
} }