ace/lib/audiodriver/wavheader.go
2022-09-26 03:04:07 +00:00

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
}