diff --git a/exp/audio/audio.go b/exp/audio/audio.go index be40491ac..19619d9ec 100644 --- a/exp/audio/audio.go +++ b/exp/audio/audio.go @@ -91,9 +91,10 @@ func (s *mixedPlayersStream) Read(b []byte) (int, error) { // TODO: Enable to specify the format like Mono8? type Context struct { - sampleRate int - stream *mixedPlayersStream - players map[*Player]struct{} + sampleRate int + stream *mixedPlayersStream + players map[*Player]struct{} + innerPlayer *player sync.Mutex } @@ -104,9 +105,11 @@ func NewContext(sampleRate int) *Context { players: map[*Player]struct{}{}, } c.stream = &mixedPlayersStream{c} - if err := startPlaying(c.stream, c.sampleRate); err != nil { + p, err := startPlaying(c.stream, c.sampleRate) + if err != nil { panic(fmt.Sprintf("audio: NewContext error: %v", err)) } + c.innerPlayer = p return c } diff --git a/exp/audio/audio_js.go b/exp/audio/audio_js.go index 41d368597..8fce228d0 100644 --- a/exp/audio/audio_js.go +++ b/exp/audio/audio_js.go @@ -31,17 +31,12 @@ type player struct { bufferSource *js.Object } -var currentPlayer *player - -func startPlaying(src io.Reader, sampleRate int) error { +func startPlaying(src io.Reader, sampleRate int) (*player, error) { // Do nothing in node.js. if js.Global.Get("require") != js.Undefined { - return nil + return nil, nil } - if currentPlayer != nil { - panic("audio: currentPlayer already exists") - } class := js.Global.Get("AudioContext") if class == js.Undefined { class = js.Global.Get("webkitAudioContext") @@ -49,17 +44,17 @@ func startPlaying(src io.Reader, sampleRate int) error { if class == js.Undefined { panic("audio: audio couldn't be initialized") } - currentPlayer = &player{ + p := &player{ src: src, sampleRate: sampleRate, bufferSource: nil, context: class.New(), } - currentPlayer.position = currentPlayer.context.Get("currentTime").Float() - if err := currentPlayer.start(); err != nil { - return err + p.position = p.context.Get("currentTime").Float() + if err := p.start(); err != nil { + return nil, err } - 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 83557d339..c633568e0 100644 --- a/exp/audio/audio_openal.go +++ b/exp/audio/audio_openal.go @@ -39,30 +39,25 @@ type player struct { isClosed bool } -var currentPlayer *player - -func startPlaying(src io.Reader, sampleRate int) error { - if currentPlayer != nil { - panic("audio: currentPlayer already exists") - } +func startPlaying(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 { panic(fmt.Sprintf("audio: al.GenSources error: %d", err)) } - currentPlayer = &player{ + p := &player{ alSource: s[0], alBuffers: []al.Buffer{}, source: src, sampleRate: sampleRate, } - runtime.SetFinalizer(currentPlayer, (*player).close) - if err := currentPlayer.start(); err != nil { - return err + runtime.SetFinalizer(p, (*player).close) + if err := p.start(); err != nil { + return nil, err } - return nil + return p, nil } const bufferSize = 1024