audio/vorbis: Avoid unnecessary appending

This commit is contained in:
Hajime Hoshi 2018-10-05 23:59:30 +09:00
parent 1cf3022ce6
commit c0884b5ab2
2 changed files with 34 additions and 18 deletions

View File

@ -16,6 +16,7 @@ package stb
import ( import (
"fmt" "fmt"
"io"
"github.com/gopherjs/gopherwasm/js" "github.com/gopherjs/gopherwasm/js"
) )
@ -37,9 +38,30 @@ func init() {
js.Global().Get("window").Call("eval", string(stbvorbis_js)) 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) ch := make(chan error)
data := []float32{} samples := &Samples{}
channels := 0 channels := 0
sampleRate := 0 sampleRate := 0
@ -68,12 +90,13 @@ func DecodeVorbis(buf []byte) ([]float32, int, int, error) {
} }
flattened := flatten.Invoke(r.Get("data")) flattened := flatten.Invoke(r.Get("data"))
d := make([]float32, flattened.Length()) s := make([]float32, flattened.Length())
arr := js.TypedArrayOf(d) arr := js.TypedArrayOf(s)
arr.Call("set", flattened) arr.Call("set", flattened)
arr.Release() arr.Release()
data = append(data, d...) samples.samples = append(samples.samples, s)
samples.length += int64(len(s)) / int64(channels)
}) })
arr := js.TypedArrayOf(buf) arr := js.TypedArrayOf(buf)
@ -84,5 +107,5 @@ func DecodeVorbis(buf []byte) ([]float32, int, int, error) {
return nil, 0, 0, err return nil, 0, 0, err
} }
return data, channels, sampleRate, nil return samples, channels, sampleRate, nil
} }

View File

@ -18,7 +18,6 @@
package vorbis package vorbis
import ( import (
"io"
"io/ioutil" "io/ioutil"
"github.com/hajimehoshi/ebiten/audio" "github.com/hajimehoshi/ebiten/audio"
@ -26,23 +25,17 @@ import (
) )
type decoderImpl struct { type decoderImpl struct {
data []float32 samples *stb.Samples
channels int channels int
sampleRate int sampleRate int
} }
func (d *decoderImpl) Read(buf []float32) (int, error) { func (d *decoderImpl) Read(buf []float32) (int, error) {
if len(d.data) == 0 { return d.samples.Read(buf)
return 0, io.EOF
}
n := copy(buf, d.data)
d.data = d.data[n:]
return n, nil
} }
func (d *decoderImpl) Length() int64 { func (d *decoderImpl) Length() int64 {
return int64(len(d.data) / d.channels) return d.samples.Length()
} }
func (d *decoderImpl) Channels() int { func (d *decoderImpl) Channels() int {
@ -59,9 +52,9 @@ func newDecoder(in audio.ReadSeekCloser) (decoder, error) {
return nil, err return nil, err
} }
data, channels, sampleRate, err := stb.DecodeVorbis(buf) samples, channels, sampleRate, err := stb.DecodeVorbis(buf)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &decoderImpl{data, channels, sampleRate}, nil return &decoderImpl{samples, channels, sampleRate}, nil
} }