86 lines
1.6 KiB
Go
86 lines
1.6 KiB
Go
package audiodriver
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"errors"
|
|
"io"
|
|
)
|
|
|
|
// Skip riff header and `fmt ` just 16 bytes
|
|
const (
|
|
FmtHeaderOffset int64 = 0x0c
|
|
FmtHeaderIDSize int64 = 4
|
|
FmtHeaderChunkSizeSize int64 = 4
|
|
)
|
|
|
|
type WavHeader struct {
|
|
ID [4]byte
|
|
Size uint32
|
|
AudioFormat uint16
|
|
NumChannels uint16
|
|
SampleRate uint32
|
|
ByteRate uint32
|
|
BlockAlign uint16
|
|
BitsPerSample uint16
|
|
}
|
|
|
|
func (w *WavHeader) Parse(f io.ReadSeeker) error {
|
|
if _, err := f.Seek(FmtHeaderOffset, io.SeekStart); err != nil {
|
|
return err
|
|
}
|
|
|
|
var id [4]byte
|
|
if _, err := f.Read(id[:]); err != nil {
|
|
return err
|
|
}
|
|
if bytes.Equal(id[:], []byte{'f', 'm', 't', '0'}[:]) {
|
|
return errors.New("bad header")
|
|
}
|
|
w.ID = id
|
|
|
|
var size [4]byte
|
|
if _, err := f.Read(size[:]); err != nil {
|
|
return err
|
|
}
|
|
w.Size = binary.LittleEndian.Uint32(size[:])
|
|
|
|
var af [2]byte
|
|
if _, err := f.Read(af[:]); err != nil {
|
|
return err
|
|
}
|
|
w.AudioFormat = binary.LittleEndian.Uint16(af[:])
|
|
|
|
var nc [2]byte
|
|
if _, err := f.Read(nc[:]); err != nil {
|
|
return err
|
|
}
|
|
w.NumChannels = binary.LittleEndian.Uint16(nc[:])
|
|
|
|
var sr [4]byte
|
|
if _, err := f.Read(sr[:]); err != nil {
|
|
return err
|
|
}
|
|
w.SampleRate = binary.LittleEndian.Uint32(sr[:])
|
|
|
|
var br [4]byte
|
|
if _, err := f.Read(br[:]); err != nil {
|
|
return err
|
|
}
|
|
w.ByteRate = binary.LittleEndian.Uint32(br[:])
|
|
|
|
var ba [2]byte
|
|
if _, err := f.Read(ba[:]); err != nil {
|
|
return err
|
|
}
|
|
w.BlockAlign = binary.LittleEndian.Uint16(ba[:])
|
|
|
|
var bps [2]byte
|
|
if _, err := f.Read(ba[:]); err != nil {
|
|
return err
|
|
}
|
|
w.BitsPerSample = binary.LittleEndian.Uint16(bps[:])
|
|
|
|
return nil
|
|
}
|