From c0884b5ab2ad8cec0895c3225a4d7dfb44ac3af0 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Fri, 5 Oct 2018 23:59:30 +0900 Subject: [PATCH] audio/vorbis: Avoid unnecessary appending --- audio/vorbis/internal/stb/decode.go | 35 ++++++++++++++++++++++++----- audio/vorbis/vorbis_js.go | 17 +++++--------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/audio/vorbis/internal/stb/decode.go b/audio/vorbis/internal/stb/decode.go index 5a923cd18..c2aae6080 100644 --- a/audio/vorbis/internal/stb/decode.go +++ b/audio/vorbis/internal/stb/decode.go @@ -16,6 +16,7 @@ package stb import ( "fmt" + "io" "github.com/gopherjs/gopherwasm/js" ) @@ -37,9 +38,30 @@ func init() { js.Global().Get("window").Call("eval", string(stbvorbis_js)) } -func DecodeVorbis(buf []byte) ([]float32, int, int, error) { +type Samples struct { + samples [][]float32 + length int64 +} + +func (s *Samples) Read(buf []float32) (int, error) { + if len(s.samples) == 0 { + return 0, io.EOF + } + n := copy(buf, s.samples[0]) + s.samples[0] = s.samples[0][n:] + if len(s.samples[0]) == 0 { + s.samples = s.samples[1:] + } + return n, nil +} + +func (s *Samples) Length() int64 { + return s.length +} + +func DecodeVorbis(buf []byte) (*Samples, int, int, error) { ch := make(chan error) - data := []float32{} + samples := &Samples{} channels := 0 sampleRate := 0 @@ -68,12 +90,13 @@ func DecodeVorbis(buf []byte) ([]float32, int, int, error) { } flattened := flatten.Invoke(r.Get("data")) - d := make([]float32, flattened.Length()) - arr := js.TypedArrayOf(d) + s := make([]float32, flattened.Length()) + arr := js.TypedArrayOf(s) arr.Call("set", flattened) arr.Release() - data = append(data, d...) + samples.samples = append(samples.samples, s) + samples.length += int64(len(s)) / int64(channels) }) arr := js.TypedArrayOf(buf) @@ -84,5 +107,5 @@ func DecodeVorbis(buf []byte) ([]float32, int, int, error) { return nil, 0, 0, err } - return data, channels, sampleRate, nil + return samples, channels, sampleRate, nil } diff --git a/audio/vorbis/vorbis_js.go b/audio/vorbis/vorbis_js.go index 1e6f82d97..704167b7b 100644 --- a/audio/vorbis/vorbis_js.go +++ b/audio/vorbis/vorbis_js.go @@ -18,7 +18,6 @@ package vorbis import ( - "io" "io/ioutil" "github.com/hajimehoshi/ebiten/audio" @@ -26,23 +25,17 @@ import ( ) type decoderImpl struct { - data []float32 + samples *stb.Samples channels int sampleRate int } func (d *decoderImpl) Read(buf []float32) (int, error) { - if len(d.data) == 0 { - return 0, io.EOF - } - - n := copy(buf, d.data) - d.data = d.data[n:] - return n, nil + return d.samples.Read(buf) } func (d *decoderImpl) Length() int64 { - return int64(len(d.data) / d.channels) + return d.samples.Length() } func (d *decoderImpl) Channels() int { @@ -59,9 +52,9 @@ func newDecoder(in audio.ReadSeekCloser) (decoder, error) { return nil, err } - data, channels, sampleRate, err := stb.DecodeVorbis(buf) + samples, channels, sampleRate, err := stb.DecodeVorbis(buf) if err != nil { return nil, err } - return &decoderImpl{data, channels, sampleRate}, nil + return &decoderImpl{samples, channels, sampleRate}, nil }