Skip to content

Commit

Permalink
default silences wav
Browse files Browse the repository at this point in the history
  • Loading branch information
pablodz committed Feb 17, 2025
1 parent a32b7a3 commit 811680b
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.2.1
v0.2.2
46 changes: 46 additions & 0 deletions audio/utils/empty.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package utils

// AudioSilenceDefault creates a WAV silence buffer with 1000 samples
func AudioSilenceDefault() []byte {
// Create 1000 samples of silence (2000 bytes for 16-bit)
empty := make([]byte, 1000)

headers := GenerateWavHeadersWithConfig(&WavHeader{
Length: uint32(len(empty) + 44), // 44 is WAV header size
WaveFormat: WAVE_FORMAT_PCM,
Channels: 1,
SampleRate: 8000,
BitDepth: 16,
Verbose: false,
})

// Combine headers and empty samples
result := make([]byte, len(headers)+len(empty))
copy(result, headers)
copy(result[len(headers):], empty)
return result
}

// AudioSilence creates a WAV silence buffer of specified duration in milliseconds
func AudioSilence(durationMs int) []byte {
// Calculate number of samples needed (8000Hz * (durationMs/1000))
numSamples := (8000 * durationMs) / 1000

// Pre-allocate the exact buffer size needed (2 bytes per sample for 16-bit)
empty := make([]byte, numSamples*2)

headers := GenerateWavHeadersWithConfig(&WavHeader{
Length: uint32(len(empty) + 44), // 44 is WAV header size
WaveFormat: WAVE_FORMAT_PCM,
Channels: 1,
SampleRate: 8000,
BitDepth: 16,
Verbose: false, // Set to false unless debugging
})

// Pre-allocate the final buffer to avoid reallocation
result := make([]byte, len(headers)+len(empty))
copy(result, headers)
copy(result[len(headers):], empty)
return result
}
88 changes: 88 additions & 0 deletions audio/utils/empty_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package utils

import (
"bytes"
"testing"
)

func TestAudioSilence(t *testing.T) {
tests := []struct {
name string
durationMs int
wantLen int // Expected total length including 44 byte header
}{
{
name: "1 second silence",
durationMs: 1000,
wantLen: 16044, // 44 + (8000 * 2) bytes
},
{
name: "500ms silence",
durationMs: 500,
wantLen: 8044, // 44 + (4000 * 2) bytes
},
{
name: "100ms silence",
durationMs: 100,
wantLen: 1644, // 44 + (800 * 2) bytes
},
{
name: "zero duration",
durationMs: 0,
wantLen: 44, // Just header
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := AudioSilence(tt.durationMs)

// Check total length
if len(got) != tt.wantLen {
t.Errorf("AudioSilence() length = %v, want %v", len(got), tt.wantLen)
}

// Verify WAV header basics
if !bytes.Equal(got[0:4], []byte("RIFF")) {
t.Error("AudioSilence() invalid RIFF header")
}
if !bytes.Equal(got[8:12], []byte("WAVE")) {
t.Error("AudioSilence() invalid WAVE format")
}

// Verify silence (all bytes should be 0 after header)
for i := 44; i < len(got); i++ {
if got[i] != 0 {
t.Errorf("AudioSilence() non-zero byte at position %d", i)
break
}
}
})
}
}

func TestAudioSilenceDefault(t *testing.T) {
got := AudioSilenceDefault()
wantLen := 1044 // 44 + (1000 * 2) bytes

// Check total length
if len(got) != wantLen {
t.Errorf("AudioSilenceDefault() length = %v, want %v", len(got), wantLen)
}

// Verify WAV header basics
if !bytes.Equal(got[0:4], []byte("RIFF")) {
t.Error("AudioSilenceDefault() invalid RIFF header")
}
if !bytes.Equal(got[8:12], []byte("WAVE")) {
t.Error("AudioSilenceDefault() invalid WAVE format")
}

// Verify silence (all bytes should be 0 after header)
for i := 44; i < len(got); i++ {
if got[i] != 0 {
t.Errorf("AudioSilenceDefault() non-zero byte at position %d", i)
break
}
}
}
8 changes: 0 additions & 8 deletions audio/utils/wav_headers.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,7 @@ func GenerateWavHeadersWithConfig(head *WavHeader) []byte {
}

totalLength := head.Length - 8
if totalLength < 0 {
log.Printf("WARNING: Length is less than 8, defaulting to 0\n")
totalLength = 0
}

subChunk2Size := head.Length - 44
if subChunk2Size < 0 {
subChunk2Size = 0
}

chunkID := []byte{'R', 'I', 'F', 'F'}
format := []byte{'W', 'A', 'V', 'E'}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/sopro-dev/sopro-core

go 1.21.5
go 1.23.4

0 comments on commit 811680b

Please sign in to comment.