From 5f3bf33213926fee73fd1c2a8fee55735e93a12b Mon Sep 17 00:00:00 2001 From: saxon Date: Mon, 21 Jan 2019 22:52:17 +1030 Subject: [PATCH] av/stream/flac/decode.go: wrote func headers --- stream/flac/decode.go | 79 ++++++++++++++++++++++++++++++---------- stream/flac/flac_test.go | 26 +++++++++++++ 2 files changed, 85 insertions(+), 20 deletions(-) diff --git a/stream/flac/decode.go b/stream/flac/decode.go index 667fcf9c..42c4dace 100644 --- a/stream/flac/decode.go +++ b/stream/flac/decode.go @@ -1,3 +1,29 @@ +/* +NAME + decode.go + +DESCRIPTION + decode.go provides functionality for the decoding of FLAC compressed audio + +AUTHOR + Saxon Nelson-Milton + +LICENSE + decode.go is Copyright (C) 2017-2019 the Australian Ocean Lab (AusOcean) + + It is free software: you can redistribute it and/or modify them + under the terms of the GNU General Public License as published by the + Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + It is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with revid in gpl.txt. If not, see http://www.gnu.org/licenses. +*/ package flac import ( @@ -10,59 +36,72 @@ import ( "github.com/mewkiz/flac" ) -const wavAudioFormat = 1 +const wavFormat = 1 -type WriterSeeker struct { +// writeSeeker implements a memory based io.WriteSeeker. +type writeSeeker struct { buf []byte pos int } -func (ws *WriterSeeker) Bytes() []byte { +// Bytes returns the bytes contained in the writeSeekers buffer. +func (ws *writeSeeker) 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 +// Write writes len(p) bytes from p to the writeSeeker's buf and returns the number +// of bytes written. If less than len(p) bytes are written, an error is returned. +func (ws *writeSeeker) Write(p []byte) (n int, err error) { + minCap := ws.pos + len(p) + if minCap > cap(ws.buf) { // Make sure buf has enough capacity: + buf2 := make([]byte, len(ws.buf), minCap+len(p)) // add some extra + copy(buf2, ws.buf) + ws.buf = buf2 } - if minCap > len(m.buf) { - m.buf = m.buf[:minCap] + if minCap > len(ws.buf) { + ws.buf = ws.buf[:minCap] } - copy(m.buf[m.pos:], p) - m.pos += len(p) + copy(ws.buf[ws.pos:], p) + ws.pos += len(p) return len(p), nil } -func (m *WriterSeeker) Seek(offset int64, whence int) (int64, error) { +// Seek sets the offset for the next Read or Write to offset, interpreted according +// to whence: SeekStart means relative to the start of the file, SeekCurrent means +// relative to the current offset, and SeekEnd means relative to the end. Seek returns +// the new offset relative to the start of the file and an error, if any. +func (ws *writeSeeker) 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 + newPos = ws.pos + offs case io.SeekEnd: - newPos = len(m.buf) + offs + newPos = len(ws.buf) + offs } if newPos < 0 { return 0, errors.New("negative result pos") } - m.pos = newPos + ws.pos = newPos return int64(newPos), nil } -// Decode takes a slice of flac and decodes to wav +// 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. r := bytes.NewReader(buf) stream, err := flac.Parse(r) if err != nil { return nil, errors.New("Could not parse FLAC") } - ws := &WriterSeeker{} - enc := wav.NewEncoder(ws, int(stream.Info.SampleRate), int(stream.Info.BitsPerSample), int(stream.Info.NChannels), wavAudioFormat) + + // 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) defer enc.Close() + var data []int for { // Decode FLAC audio samples. diff --git a/stream/flac/flac_test.go b/stream/flac/flac_test.go index 13bef836..d69c0494 100644 --- a/stream/flac/flac_test.go +++ b/stream/flac/flac_test.go @@ -1,3 +1,29 @@ +/* +NAME + flac_test.go + +DESCRIPTION + flac_test.go provides utilities to test FLAC audio decoding + +AUTHOR + Saxon Nelson-Milton + +LICENSE + flac_test.go is Copyright (C) 2017-2019 the Australian Ocean Lab (AusOcean) + + It is free software: you can redistribute it and/or modify them + under the terms of the GNU General Public License as published by the + Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + It is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with revid in gpl.txt. If not, see http://www.gnu.org/licenses. +*/ package flac import (