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
 | |
| }
 |