-
Notifications
You must be signed in to change notification settings - Fork 39
/
Copy pathwavefile.go
110 lines (98 loc) Β· 9.14 KB
/
wavefile.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
106
107
108
109
110
package wave
// representation of the wave file, used by reader.go and writer.go
// Frame is a single float64 value of raw audio data
type Frame float64
/*
ββββββββββ€βββββββββββββββββ€βββββββ€ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Offset β Field β Size β -- start of header β
β βββββββββͺβββββββββββββββββͺβββββββͺββββββββββββββββββββββββββββββββββββββββββββββββββββ£
β 0 β ChunkID β 4 β β
ββββββββββΌβββββββββββββββββΌβββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ’
β 4 β ChunkSize β 4 β β
ββββββββββΌβββββββββββββββββΌβββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ’
β 8 β Format β 8 β β
ββββββββββΌβββββββββββββββββΌβββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ’
β -- β -- β -- β -- start of fmt β
ββββββββββΌβββββββββββββββββΌβββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ’
β 12 β SubchunkID β 4 β β
ββββββββββΌβββββββββββββββββΌβββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ’
β 16 β SubchunkSize β 4 β β
ββββββββββΌβββββββββββββββββΌβββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ’
β 20 β AudioFormat β 2 β β
ββββββββββΌβββββββββββββββββΌβββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ’
β 22 β NumChannels β 2 β β
ββββββββββΌβββββββββββββββββΌβββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ’
β 24 β SampleRate β 4 β β
ββββββββββΌβββββββββββββββββΌβββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ’
β 28 β ByteRate β 4 β β
ββββββββββΌβββββββββββββββββΌβββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ’
β 32 β BlockAlign β 2 β β
ββββββββββΌβββββββββββββββββΌβββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ’
β 34 β BitsPerSample β 2 β β
ββββββββββΌβββββββββββββββββΌβββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ’
β * 36 β ExtraParamSize β 2 β Optional! Only when not PCM β
ββββββββββΌβββββββββββββββββΌβββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ’
β * 38 β ExtraParams β * β Optional! Only when not PCM β
ββββββββββΌβββββββββββββββββΌβββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ’
β -- β -- β -- β -- start of data, assuming PCM β
ββββββββββΌβββββββββββββββββΌβββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ’
β 36 β Subchunk2ID β 4 β (offset by extra params of subchunk 1 if not PCM) β
ββββββββββΌβββββββββββββββββΌβββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ’
β 40 β SubchunkSize β 4 β (offset by extra params of subchunk 1 if not PCM) β
ββββββββββΌβββββββββββββββββΌβββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββ’
β 44 β Data β * β (offset by extra params of subchunk 1 if not PCM) β
ββββββββββ§βββββββββββββββββ§βββββββ§ββββββββββββββββββββββββββββββββββββββββββββββββββββ
*/
// Wave represents an entire .wav audio file
type Wave struct {
WaveHeader
WaveFmt
WaveData
}
// WaveHeader describes the header each WAVE file should start with
type WaveHeader struct {
ChunkID []byte // should be RIFF on little-endian or RIFX on big-endian systems..
ChunkSize int
Format string // sanity-check, should be WAVE (//TODO: keep as []byte?)
}
// WaveFmt describes the format of the sound-information in the data subchunks
type WaveFmt struct {
Subchunk1ID []byte // should contain "fmt"
Subchunk1Size int // 16 for PCM
AudioFormat int // PCM = 1 (Linear Quantization), if not 1, compression was used.
NumChannels int // Mono 1, Stereo = 2, ..
SampleRate int // 44100 for CD-Quality, etc..
ByteRate int // SampleRate * NumChannels * BitsPerSample / 8
BlockAlign int // NumChannels * BitsPerSample / 8 (number of bytes per sample)
BitsPerSample int // 8 bits = 8, 16 bits = 16, .. :-)
ExtraParamSize int // if not PCM, can contain extra params
ExtraParams []byte // the actual extra params.
}
// WaveData contains the raw sound data
type WaveData struct {
Subchunk2ID []byte // Identifier of subchunk
Subchunk2Size int // size of raw sound data
RawData []byte // raw sound data itself
Frames []Frame
}
// NewWaveFmt can be used to generate a complete WaveFmt by calculating the remaining props
func NewWaveFmt(format, channels, samplerate, bitspersample int, extraparams []byte) WaveFmt {
return WaveFmt{
Subchunk1ID: Format,
Subchunk1Size: 16, // assume PCM for now
AudioFormat: format,
NumChannels: channels,
SampleRate: samplerate,
ByteRate: samplerate * channels * (bitspersample / 8.0),
BlockAlign: channels * (bitspersample / 8),
BitsPerSample: bitspersample,
ExtraParamSize: len(extraparams),
ExtraParams: extraparams,
}
}
// SetChannels changes the FMT to adapt to a new amount of channels
func (wfmt *WaveFmt) SetChannels(n uint) {
wfmt.NumChannels = int(n)
wfmt.ByteRate = (wfmt.SampleRate * wfmt.NumChannels * wfmt.BitsPerSample) / 8
wfmt.BlockAlign = (wfmt.NumChannels * wfmt.BitsPerSample) / 8
}