go-opengl-pixel/audio/wav/header.go

79 lines
1.8 KiB
Go

package wav
import (
"encoding/binary"
"io"
"github.com/pkg/errors"
)
type header struct {
fileSize int32
formatSize int32
formatType int16
numChans int16
sampleRate int32
byteRate int32
bytesPerFrame int16
bitsPerSample int16
dataSize int32
}
func readHeader(r io.Reader) (header, error) {
var (
h header
er errReader
)
err := er.
ReadString(r, "RIFF", errors.New("missing RIFF at the beginning")).
ReadBinary(r, binary.LittleEndian, &h.fileSize).
ReadString(r, "WAVE", errors.New("unsupported file type")).
ReadString(r, "fmt\x00", errors.New("missing format chunk marker")).
ReadBinary(r, binary.LittleEndian, &h.formatSize).
ReadBinary(r, binary.LittleEndian, &h.formatType).
ReadBinary(r, binary.LittleEndian, &h.numChans).
ReadBinary(r, binary.LittleEndian, &h.sampleRate).
ReadBinary(r, binary.LittleEndian, &h.byteRate).
ReadBinary(r, binary.LittleEndian, &h.bytesPerFrame).
ReadBinary(r, binary.LittleEndian, &h.bitsPerSample).
ReadString(r, "data", errors.New("missing data chunk marker")).
ReadBinary(r, binary.LittleEndian, &h.dataSize).
Err()
return h, err
}
type errReader struct {
err error
}
func (e *errReader) ReadString(r io.Reader, s string, notThereErr error) *errReader {
if e.err != nil {
return e
}
buf := make([]byte, len(s))
_, err := r.Read(buf)
if err != nil {
e.err = errors.Wrap(err, "error while reading header")
return e
}
if string(buf) != s {
e.err = errors.Wrap(err, "invalid header")
}
return e
}
func (e *errReader) ReadBinary(r io.Reader, order binary.ByteOrder, data interface{}) *errReader {
if e.err != nil {
return e
}
err := binary.Read(r, order, data)
if err != nil {
e.err = errors.Wrap(err, "invalid header")
}
return e
}
func (e *errReader) Err() error {
return e.err
}