-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwav2pcm.go
49 lines (42 loc) · 1.37 KB
/
wav2pcm.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
package wav2opus
import (
"encoding/binary"
"errors"
)
// WAVToPCM WAVデータをPCMデータに変換します。
//
// 引数:
//
// wavData: 入力WAVデータのバイトスライス
// inputRate: 入力サンプリングレート 0の場合はWAVヘッダーから読み取ります
// outputRate: 出力サンプリングレート 0の場合は入力サンプリングレートと同じに設定されます
//
// 戻り値:
//
// PCMデータのint16スライスとエラー(発生した場合)
func WAVToPCM(wavData []byte, inputRate int, outputRate int) ([]int16, error) {
const wavHeaderSize = 44
var wavSize = len(wavData)
if wavSize < wavHeaderSize {
return nil, errors.New("wav data too short")
}
if inputRate == 0 {
inputRate = int(binary.LittleEndian.Uint32(wavData[24:28]))
}
if outputRate == 0 {
outputRate = inputRate
}
if (wavSize-wavHeaderSize)%2 == 1 {
return nil, errors.New("illegal wav data: payload must be encoded in byte pairs")
}
numPCMSamples := (wavSize - wavHeaderSize) / 2
PCMsamples := make([]int16, numPCMSamples)
for i := 0; i < numPCMSamples; i++ {
PCMsamples[i] += int16(wavData[wavHeaderSize+i*2])
PCMsamples[i] += int16(wavData[wavHeaderSize+i*2+1]) << 8
}
if inputRate != outputRate {
PCMsamples = ResamplePCM(PCMsamples, inputRate, outputRate)
}
return PCMsamples, nil
}