-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathdecoder.go
105 lines (81 loc) · 2.35 KB
/
decoder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package waveform
import (
"encoding/binary"
"errors"
"math"
)
// Parser type
type Parser func([]byte) float64
// DecodeWav decode wav file information from bytes
func DecodeWav(bytes []byte) *Wav {
waveFormat := WaveFormat(binary.LittleEndian.Uint16(bytes[20:22]))
numChannels := binary.LittleEndian.Uint16(bytes[22:24])
sampleRate := binary.LittleEndian.Uint32(bytes[24:28])
bitsPerSample := binary.LittleEndian.Uint16(bytes[34:36])
subchunk1Size := binary.LittleEndian.Uint32(bytes[16:20])
subchunk2Start := 20 + subchunk1Size
subchunk2ID := string(bytes[subchunk2Start : subchunk2Start+4])
subchunk2Size := binary.LittleEndian.Uint32(bytes[subchunk2Start+4 : subchunk2Start+8])
dataStart := subchunk2Start + 8
dataSize := subchunk2Size
if subchunk2ID == "fact" {
subchunk3Start := subchunk2Start + 8 + subchunk2Size
subchunk3Size := binary.LittleEndian.Uint32(bytes[subchunk3Start+4 : subchunk3Start+8])
dataStart = subchunk3Start + 8
dataSize = subchunk3Size
}
data := bytes[dataStart : dataStart+dataSize]
return &Wav{
WaveFormat: waveFormat,
NumChannels: numChannels,
SampleRate: sampleRate,
BitsPerSample: bitsPerSample,
DataChuckSize: dataSize,
Data: data,
}
}
// 0 to 255
func int8BitsParser(b []byte) float64 {
return float64(b[0])
}
// -32768 to 32767
func int16BitsParser(b []byte) float64 {
value := int16(binary.LittleEndian.Uint16(b))
return float64(value)
}
func int32BitsParser(b []byte) float64 {
value := int32(binary.LittleEndian.Uint32(b))
return float64(value)
}
func float32BitsParser(b []byte) float64 {
bits := binary.LittleEndian.Uint32(b)
value := math.Float32frombits(bits)
return float64(value)
}
func float64BitsParser(b []byte) float64 {
bits := binary.LittleEndian.Uint64(b)
return math.Float64frombits(bits)
}
// GetSampleParser get sample parser
func GetSampleParser(bitsPerSample uint16, waveFormat WaveFormat) (func([]byte) float64, error) {
if waveFormat == WaveFormatPCM {
if bitsPerSample == 8 {
return int8BitsParser, nil
}
if bitsPerSample == 16 {
return int16BitsParser, nil
}
if bitsPerSample == 32 {
return int32BitsParser, nil
}
}
if waveFormat == WaveFormatIEEEFloat {
if bitsPerSample == 32 {
return float32BitsParser, nil
}
if bitsPerSample == 64 {
return float64BitsParser, nil
}
}
return nil, errors.New("format not support")
}