diff --git a/exp/audio/audio.go b/exp/audio/audio.go index 837cb5287..b25796f40 100644 --- a/exp/audio/audio.go +++ b/exp/audio/audio.go @@ -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 } diff --git a/exp/audio/audio_js.go b/exp/audio/audio_js.go index ae8f5ba0f..0d073609f 100644 --- a/exp/audio/audio_js.go +++ b/exp/audio/audio_js.go @@ -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) { diff --git a/exp/audio/audio_openal.go b/exp/audio/audio_openal.go index eb9429f1c..ddef418d5 100644 --- a/exp/audio/audio_openal.go +++ b/exp/audio/audio_openal.go @@ -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 ( diff --git a/exp/audio/audio_windows.go b/exp/audio/audio_windows.go index 989a21d1c..d28c70373 100644 --- a/exp/audio/audio_windows.go +++ b/exp/audio/audio_windows.go @@ -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 {