diff --git a/stream/flac/decode.go b/stream/flac/decode.go index 6c8445e4..667fcf9c 100644 --- a/stream/flac/decode.go +++ b/stream/flac/decode.go @@ -4,16 +4,55 @@ import ( "bytes" "errors" "io" - "io/ioutil" "github.com/go-audio/audio" "github.com/go-audio/wav" "github.com/mewkiz/flac" - "github.com/orcaman/writerseeker" ) const wavAudioFormat = 1 +type WriterSeeker struct { + buf []byte + pos int +} + +func (ws *WriterSeeker) Bytes() []byte { + return ws.buf +} + +func (m *WriterSeeker) Write(p []byte) (n int, err error) { + minCap := m.pos + len(p) + if minCap > cap(m.buf) { // Make sure buf has enough capacity: + buf2 := make([]byte, len(m.buf), minCap+len(p)) // add some extra + copy(buf2, m.buf) + m.buf = buf2 + } + if minCap > len(m.buf) { + m.buf = m.buf[:minCap] + } + copy(m.buf[m.pos:], p) + m.pos += len(p) + return len(p), nil +} + +func (m *WriterSeeker) Seek(offset int64, whence int) (int64, error) { + newPos, offs := 0, int(offset) + switch whence { + case io.SeekStart: + newPos = offs + case io.SeekCurrent: + newPos = m.pos + offs + case io.SeekEnd: + newPos = len(m.buf) + offs + } + if newPos < 0 { + return 0, errors.New("negative result pos") + } + m.pos = newPos + return int64(newPos), nil +} + // Decode takes a slice of flac and decodes to wav func Decode(buf []byte) ([]byte, error) { r := bytes.NewReader(buf) @@ -21,7 +60,7 @@ func Decode(buf []byte) ([]byte, error) { if err != nil { return nil, errors.New("Could not parse FLAC") } - ws := &writerseeker.WriterSeeker{} + ws := &WriterSeeker{} enc := wav.NewEncoder(ws, int(stream.Info.SampleRate), int(stream.Info.BitsPerSample), int(stream.Info.NChannels), wavAudioFormat) defer enc.Close() var data []int @@ -54,9 +93,6 @@ func Decode(buf []byte) ([]byte, error) { return nil, err } } - d, err := ioutil.ReadAll(ws.Reader()) - if err != nil { - return nil, err - } - return d, nil + + return ws.Bytes(), nil }