wav: read_hdr
This commit is contained in:
parent
df563fd7f2
commit
9a19449fc8
BIN
data/sample.wav
Normal file
BIN
data/sample.wav
Normal file
Binary file not shown.
119
wav.go
Normal file
119
wav.go
Normal file
|
@ -0,0 +1,119 @@
|
|||
package tta
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
RIFF_SIGN = (0x46464952)
|
||||
WAVE_SIGN = (0x45564157)
|
||||
fmt_SIGN = (0x20746D66)
|
||||
data_SIGN = (0x61746164)
|
||||
|
||||
WAVE_FORMAT_PCM = 1
|
||||
WAVE_FORMAT_EXTENSIBLE = 0xFFFE
|
||||
PCM_BUFFER_LENGTH = 5120
|
||||
)
|
||||
|
||||
type WAVE_hdr struct {
|
||||
chunk_id uint32
|
||||
chunk_size uint32
|
||||
format uint32
|
||||
subchunk_id uint32
|
||||
subchunk_size uint32
|
||||
audio_format uint16
|
||||
num_channels uint16
|
||||
sample_rate uint32
|
||||
byte_rate uint32
|
||||
block_align uint16
|
||||
bits_per_sample uint16
|
||||
}
|
||||
|
||||
type WAVE_subchunk_hdr struct {
|
||||
subchunk_id uint32
|
||||
subchunk_size uint32
|
||||
}
|
||||
|
||||
type WAVE_subformat struct {
|
||||
f1 uint32
|
||||
f2 uint16
|
||||
f3 uint16
|
||||
f4 [8]byte
|
||||
}
|
||||
|
||||
type WAVE_ext_hdr struct {
|
||||
cb_size uint16
|
||||
valid_bits uint16
|
||||
ch_mask uint32
|
||||
est WAVE_subformat
|
||||
}
|
||||
|
||||
func (this *WAVE_hdr) toSlice() []byte {
|
||||
size := int(unsafe.Sizeof(*this))
|
||||
return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
|
||||
Data: uintptr(unsafe.Pointer(this)),
|
||||
Len: int(size),
|
||||
Cap: int(size),
|
||||
}))
|
||||
}
|
||||
|
||||
func (this *WAVE_subchunk_hdr) toSlice() []byte {
|
||||
size := int(unsafe.Sizeof(*this))
|
||||
return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
|
||||
Data: uintptr(unsafe.Pointer(this)),
|
||||
Len: int(size),
|
||||
Cap: int(size),
|
||||
}))
|
||||
}
|
||||
|
||||
func (this *WAVE_ext_hdr) toSlice() []byte {
|
||||
size := int(unsafe.Sizeof(*this))
|
||||
return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
|
||||
Data: uintptr(unsafe.Pointer(this)),
|
||||
Len: int(size),
|
||||
Cap: int(size),
|
||||
}))
|
||||
}
|
||||
|
||||
func (this *WAVE_hdr) Read(infile *os.File) (subchunk_size uint32, err error) {
|
||||
var default_subchunk_size uint32 = 16
|
||||
b := this.toSlice()
|
||||
// Read WAVE header
|
||||
if _, err = infile.Read(b); err != nil {
|
||||
return
|
||||
}
|
||||
if this.audio_format == WAVE_FORMAT_EXTENSIBLE {
|
||||
wave_hdr_ex := WAVE_ext_hdr{}
|
||||
if _, err = infile.Read(wave_hdr_ex.toSlice()); err != nil {
|
||||
return
|
||||
}
|
||||
default_subchunk_size += uint32(unsafe.Sizeof(wave_hdr_ex))
|
||||
this.audio_format = uint16(wave_hdr_ex.est.f1)
|
||||
}
|
||||
|
||||
// Skip extra format bytes
|
||||
if this.subchunk_size > default_subchunk_size {
|
||||
extra_len := this.subchunk_size - default_subchunk_size
|
||||
if _, err = infile.Seek(int64(extra_len), os.SEEK_SET); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Skip unsupported chunks
|
||||
subchunk_hdr := WAVE_subchunk_hdr{}
|
||||
for {
|
||||
if _, err = infile.Read(subchunk_hdr.toSlice()); err != nil {
|
||||
return
|
||||
}
|
||||
if subchunk_hdr.subchunk_id == data_SIGN {
|
||||
break
|
||||
}
|
||||
if _, err = infile.Seek(int64(subchunk_hdr.subchunk_size), os.SEEK_SET); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
subchunk_size = subchunk_hdr.subchunk_size
|
||||
return
|
||||
}
|
28
wav_test.go
Normal file
28
wav_test.go
Normal file
|
@ -0,0 +1,28 @@
|
|||
package tta
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestReadHeader(t *testing.T) {
|
||||
file, err := os.Open("./data/sample.wav")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
wav := WAVE_hdr{}
|
||||
wav_slice := []byte{0x52, 0x49, 0x46, 0x46, 0x98, 0x03, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20,
|
||||
0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00,
|
||||
0x04, 0x00, 0x10, 0x00}
|
||||
if size, err := wav.Read(file); err != nil {
|
||||
t.Error(err)
|
||||
} else {
|
||||
b := wav.toSlice()
|
||||
fmt.Printf("sample wav header: %x, %x\n", b, size)
|
||||
if bytes.Compare(wav_slice, b) != 0 {
|
||||
t.Error("WAVE_hdr::Read fail")
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue