audio: Refactoring: Unify loop

This commit is contained in:
Hajime Hoshi 2016-04-04 23:42:44 +09:00
parent cc51bc2a08
commit b6a02ddc94
4 changed files with 29 additions and 66 deletions

View File

@ -15,7 +15,6 @@
package audio
import (
"fmt"
"io"
"runtime"
"sync"
@ -121,9 +120,25 @@ func NewContext(sampleRate int) (*Context, error) {
c.stream = &mixedPlayersStream{
context: c,
}
if err := startPlaying(c.stream, c.sampleRate); err != nil {
return nil, fmt.Errorf("audio: NewContext error: %v", err)
p, err := newPlayer(c.stream, c.sampleRate)
if err != nil {
return nil, err
}
go func() {
// TODO: Is it OK to close asap?
defer p.close()
for {
err := p.proceed()
if err == io.EOF {
break
}
if err != nil {
// TODO: Record the last error
panic(err)
}
time.Sleep(1 * time.Millisecond)
}
}()
return c, nil
}

View File

@ -19,7 +19,6 @@ package audio
import (
"errors"
"io"
"time"
"github.com/gopherjs/gopherjs/js"
"github.com/hajimehoshi/ebiten"
@ -33,18 +32,13 @@ type player struct {
bufferSource *js.Object
}
func startPlaying(src io.Reader, sampleRate int) error {
// Do nothing in node.js.
if js.Global.Get("require") != js.Undefined {
return nil
}
func newPlayer(src io.Reader, sampleRate int) (*player, error) {
class := js.Global.Get("AudioContext")
if class == js.Undefined {
class = js.Global.Get("webkitAudioContext")
}
if class == js.Undefined {
return errors.New("audio: audio couldn't be initialized")
return nil, errors.New("audio: audio couldn't be initialized")
}
p := &player{
src: src,
@ -53,21 +47,7 @@ func startPlaying(src io.Reader, sampleRate int) error {
context: class.New(),
}
p.positionInSamples = int64(p.context.Get("currentTime").Float() * float64(p.sampleRate))
go func() {
defer p.close()
for {
err := p.proceed()
if err == io.EOF {
break
}
if err != nil {
// TODO: Record the last error
panic(err)
}
time.Sleep(1 * time.Millisecond)
}
}()
return nil
return p, nil
}
func toLR(data []byte) ([]int16, []int16) {

View File

@ -40,13 +40,13 @@ type player struct {
isClosed bool
}
func startPlaying(src io.Reader, sampleRate int) error {
func newPlayer(src io.Reader, sampleRate int) (*player, error) {
if e := al.OpenDevice(); e != nil {
return fmt.Errorf("audio: OpenAL initialization failed: %v", e)
return nil, fmt.Errorf("audio: OpenAL initialization failed: %v", e)
}
s := al.GenSources(1)
if err := al.Error(); err != 0 {
return fmt.Errorf("audio: al.GenSources error: %d", err)
return nil, fmt.Errorf("audio: al.GenSources error: %d", err)
}
p := &player{
alSource: s[0],
@ -74,24 +74,7 @@ func startPlaying(src io.Reader, sampleRate int) error {
p.alBuffers = []al.Buffer{}
}
al.PlaySources(p.alSource)
go func() {
// TODO: Is it OK to close asap?
defer p.close()
for {
err := p.proceed()
if err == io.EOF {
break
}
if err != nil {
// TODO: Record the last error
panic(err)
}
//time.Sleep(1 * time.Second / ebiten.FPS / 2)
time.Sleep(1 * time.Millisecond)
}
}()
return nil
return p, nil
}
const (

View File

@ -28,7 +28,6 @@ import (
"errors"
"fmt"
"io"
"time"
"unsafe"
)
@ -86,7 +85,7 @@ type player struct {
const bufferSize = 1024
func startPlaying(src io.Reader, sampleRate int) error {
func newPlayer(src io.Reader, sampleRate int) (*player, error) {
const numBlockAlign = channelNum * bitsPerSample / 8
f := C.WAVEFORMATEX{
wFormatTag: C.WAVE_FORMAT_PCM,
@ -98,7 +97,7 @@ func startPlaying(src io.Reader, sampleRate int) error {
}
var w C.HWAVEOUT
if err := C.waveOutOpen2(&w, &f); err != C.MMSYSERR_NOERROR {
return fmt.Errorf("audio: waveOutOpen error: %d", err)
return nil, fmt.Errorf("audio: waveOutOpen error: %d", err)
}
p := &player{
src: src,
@ -110,24 +109,10 @@ func startPlaying(src io.Reader, sampleRate int) error {
var err error
p.headers[i], err = newHeader(w, bufferSize)
if err != nil {
return err
return nil, err
}
}
go func() {
defer p.close()
for {
err := p.proceed()
if err == io.EOF {
break
}
if err != nil {
// TODO: Propagate this error?
panic(err)
}
time.Sleep(1 * time.Millisecond)
}
}()
return nil
return p, nil
}
func (p *player) proceed() error {