diff --git a/stream/flac/decode.go b/stream/flac/decode.go index 42c4dace..5a470370 100644 --- a/stream/flac/decode.go +++ b/stream/flac/decode.go @@ -90,7 +90,8 @@ func (ws *writeSeeker) Seek(offset int64, whence int) (int64, error) { // Decode takes buf, a slice of FLAC, and decodes to WAV. If complete decoding // fails, an error is returned. func Decode(buf []byte) ([]byte, error) { - // Lex and decode the FLAC into a stream to hold audio and properties. + + // Lex the FLAC into a stream to hold audio and it's properties. r := bytes.NewReader(buf) stream, err := flac.Parse(r) if err != nil { @@ -99,17 +100,30 @@ func Decode(buf []byte) ([]byte, error) { // Create WAV encoder and pass writeSeeker that will store output WAV. ws := &writeSeeker{} - enc := wav.NewEncoder(ws, int(stream.Info.SampleRate), int(stream.Info.BitsPerSample), int(stream.Info.NChannels), wavFormat) + sr := int(stream.Info.SampleRate) + bps := int(stream.Info.BitsPerSample) + nc := int(stream.Info.NChannels) + enc := wav.NewEncoder(ws, sr, bps, nc, wavFormat) defer enc.Close() + // Decode FLAC into frames of samples + intBuf := &audio.IntBuffer{ + Format: &audio.Format{NumChannels: nc, SampleRate: sr}, + SourceBitDepth: bps, + } + return decodeFrames(stream, intBuf, enc, ws) +} + +// +func decodeFrames(s *flac.Stream, intBuf *audio.IntBuffer, e *wav.Encoder, ws *writeSeeker) ([]byte, error) { var data []int for { - // Decode FLAC audio samples. - frame, err := stream.ParseNext() - if err != nil { - if err == io.EOF { - break - } + frame, err := s.ParseNext() + + // If we've reached the end of the stream then we can output the writeSeeker's buffer. + if err == io.EOF { + return ws.Bytes(), nil + } else if err != nil { return nil, err } @@ -120,18 +134,9 @@ func Decode(buf []byte) ([]byte, error) { data = append(data, int(subframe.Samples[i])) } } - buf := &audio.IntBuffer{ - Format: &audio.Format{ - NumChannels: int(stream.Info.NChannels), - SampleRate: int(stream.Info.SampleRate), - }, - Data: data, - SourceBitDepth: int(stream.Info.BitsPerSample), - } - if err := enc.Write(buf); err != nil { + intBuf.Data = data + if err := e.Write(intBuf); err != nil { return nil, err } } - - return ws.Bytes(), nil }