package flac 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 // Decode takes a slice of flac and decodes to wav func Decode(buf []byte) ([]byte, error) { r := bytes.NewReader(buf) stream, err := flac.Parse(r) if err != nil { return nil, errors.New("Could not parse FLAC") } ws := &writerseeker.WriterSeeker{} enc := wav.NewEncoder(ws, int(stream.Info.SampleRate), int(stream.Info.BitsPerSample), int(stream.Info.NChannels), wavAudioFormat) defer enc.Close() var data []int var out []byte var d []byte for { // Decode FLAC audio samples. frame, err := stream.ParseNext() if err != nil { if err == io.EOF { break } return nil, err } // Encode WAV audio samples. data = data[:0] for i := 0; i < frame.Subframes[0].NSamples; i++ { for _, subframe := range frame.Subframes { 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 { return nil, err } d, err = ioutil.ReadAll(ws.Reader()) if err != nil { return nil, err } out = append(out, d...) } return d, nil }