Ver código fonte

feat: parse wav metadata for offline audio source

tags/v0.4.0-pre
Jan Svabenik 1 mês atrás
pai
commit
2ccb9f6ab8
2 arquivos alterados com 23 adições e 3 exclusões
  1. +17
    -3
      internal/audio/wav.go
  2. +6
    -0
      internal/audio/wav_test.go

+ 17
- 3
internal/audio/wav.go Ver arquivo

@@ -8,8 +8,10 @@ import (
) )


type WAVSource struct { type WAVSource struct {
frames []Frame
index int
frames []Frame
index int
SampleRate int
Channels int
} }


func LoadWAVSource(path string) (*WAVSource, error) { func LoadWAVSource(path string) (*WAVSource, error) {
@@ -27,16 +29,24 @@ func LoadWAVSource(path string) (*WAVSource, error) {
return nil, fmt.Errorf("unsupported wav header") return nil, fmt.Errorf("unsupported wav header")
} }


audioFormat := binary.LittleEndian.Uint16(header[20:22])
channels := binary.LittleEndian.Uint16(header[22:24]) channels := binary.LittleEndian.Uint16(header[22:24])
sampleRate := binary.LittleEndian.Uint32(header[24:28])
bitsPerSample := binary.LittleEndian.Uint16(header[34:36]) bitsPerSample := binary.LittleEndian.Uint16(header[34:36])
dataSize := binary.LittleEndian.Uint32(header[40:44]) dataSize := binary.LittleEndian.Uint32(header[40:44])


if audioFormat != 1 {
return nil, fmt.Errorf("only PCM wav supported")
}
if bitsPerSample != 16 { if bitsPerSample != 16 {
return nil, fmt.Errorf("only 16-bit PCM wav supported") return nil, fmt.Errorf("only 16-bit PCM wav supported")
} }
if channels != 1 && channels != 2 { if channels != 1 && channels != 2 {
return nil, fmt.Errorf("only mono/stereo wav supported") return nil, fmt.Errorf("only mono/stereo wav supported")
} }
if sampleRate == 0 {
return nil, fmt.Errorf("invalid wav sample rate")
}


raw := make([]byte, dataSize) raw := make([]byte, dataSize)
if _, err := io.ReadFull(f, raw); err != nil { if _, err := io.ReadFull(f, raw); err != nil {
@@ -54,7 +64,11 @@ func LoadWAVSource(path string) (*WAVSource, error) {
frames = append(frames, NewFrame(l, r)) frames = append(frames, NewFrame(l, r))
} }


return &WAVSource{frames: frames}, nil
return &WAVSource{
frames: frames,
SampleRate: int(sampleRate),
Channels: int(channels),
}, nil
} }


func (s *WAVSource) NextFrame() Frame { func (s *WAVSource) NextFrame() Frame {


+ 6
- 0
internal/audio/wav_test.go Ver arquivo

@@ -28,5 +28,11 @@ func TestLoadWAVSource(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("LoadWAVSource failed: %v", err) t.Fatalf("LoadWAVSource failed: %v", err)
} }
if src.SampleRate != 48000 {
t.Fatalf("unexpected sample rate: %d", src.SampleRate)
}
if src.Channels != 1 {
t.Fatalf("unexpected channels: %d", src.Channels)
}
_ = src.NextFrame() _ = src.NextFrame()
} }

Carregando…
Cancelar
Salvar