From 1fec0d8203d098c576a97c9629b61c606d71b55a Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Thu, 11 Feb 2016 18:43:11 +0900 Subject: [PATCH] audio: Refactoring --- exp/audio/audio.go | 10 +++------- exp/audio/audio_js.go | 42 +++++++++++++++++++-------------------- exp/audio/audio_openal.go | 18 +++++++++++++---- 3 files changed, 38 insertions(+), 32 deletions(-) diff --git a/exp/audio/audio.go b/exp/audio/audio.go index c93cfcfaf..d7ad6acc8 100644 --- a/exp/audio/audio.go +++ b/exp/audio/audio.go @@ -19,8 +19,7 @@ import ( ) type Player struct { - src io.ReadSeeker - sampleRate int + *player } // NewPlayer creates a new player with the given data to the given channel. @@ -32,12 +31,9 @@ type Player struct { // // TODO: Pass sample rate and num of channels. func NewPlayer(src io.ReadSeeker, sampleRate int) *Player { - return &Player{ - src: src, - sampleRate: sampleRate, - } + return newPlayer(src, sampleRate) } func (p *Player) Play() error { - return play(p.src, p.sampleRate) + return p.play() } diff --git a/exp/audio/audio_js.go b/exp/audio/audio_js.go index 974fba1f3..53dcd3c07 100644 --- a/exp/audio/audio_js.go +++ b/exp/audio/audio_js.go @@ -17,7 +17,6 @@ package audio import ( - "errors" "io" "io/ioutil" @@ -26,12 +25,27 @@ import ( var context *js.Object -type audioProcessor struct { +type player struct { src io.ReadSeeker sampleRate int position float64 } +func newPlayer(src io.ReadSeeker, sampleRate int) *Player { + if context == nil { + if !initialize() { + panic("audio couldn't be initialized") + } + } + + p := &player{ + src: src, + sampleRate: sampleRate, + position: context.Get("currentTime").Float(), + } + return &Player{p} +} + func toLR(data []byte) ([]int16, []int16) { l := make([]int16, len(data)/4) r := make([]int16, len(data)/4) @@ -42,9 +56,9 @@ func toLR(data []byte) ([]int16, []int16) { return l, r } -func (a *audioProcessor) play() error { +func (p *player) play() error { // TODO: Reading all data at once is temporary implemntation. Treat this as stream. - buf, err := ioutil.ReadAll(a.src) + buf, err := ioutil.ReadAll(p.src) if err != nil { return err } @@ -53,7 +67,7 @@ func (a *audioProcessor) play() error { } const channelNum = 2 const bytesPerSample = channelNum * 16 / 8 - b := context.Call("createBuffer", channelNum, len(buf)/bytesPerSample, a.sampleRate) + b := context.Call("createBuffer", channelNum, len(buf)/bytesPerSample, p.sampleRate) l := b.Call("getChannelData", 0) r := b.Call("getChannelData", 1) il, ir := toLR(buf) @@ -65,25 +79,11 @@ func (a *audioProcessor) play() error { s := context.Call("createBufferSource") s.Set("buffer", b) s.Call("connect", context.Get("destination")) - s.Call("start", a.position) - a.position += b.Get("duration").Float() + s.Call("start", p.position) + p.position += b.Get("duration").Float() return nil } -func play(src io.ReadSeeker, sampleRate int) error { - if context == nil { - if !initialize() { - return errors.New("audio couldn't be initialized") - } - } - a := &audioProcessor{ - src: src, - sampleRate: sampleRate, - position: context.Get("currentTime").Float(), - } - return a.play() -} - func initialize() bool { // Do nothing in node.js. if js.Global.Get("require") != js.Undefined { diff --git a/exp/audio/audio_openal.go b/exp/audio/audio_openal.go index 7a5035ba1..18e9ffc43 100644 --- a/exp/audio/audio_openal.go +++ b/exp/audio/audio_openal.go @@ -30,13 +30,23 @@ func (r *readSeekCloser) Close() error { return nil } -func play(src io.ReadSeeker, sampleRate int) error { - // TODO: audio.NewPlayer interprets WAV header, which we don't want. - // Use OpenAL or native API instead. +type player struct { + *audio.Player +} + +func newPlayer(src io.ReadSeeker, sampleRate int) *Player { p, err := audio.NewPlayer(&readSeekCloser{src}, audio.Stereo16, int64(sampleRate)) if err != nil { - return err + // TODO: Should we return errors for this method? + panic(err) } + pp := &player{p} + return &Player{pp} +} + +func (p *player) play() error { + // TODO: audio.NewPlayer interprets WAV header, which we don't want. + // Use OpenAL or native API instead. return p.Play() }