d52f60c54e
- Add CalendarEvents method to recordingAPI in auth_test.go - Add CalendarEvents method to fakeCore in handlers_test.go Co-Authored-By: opencode <opencode@anthropic.com>
105 lines
2.9 KiB
Go
105 lines
2.9 KiB
Go
package audio
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"testing"
|
|
)
|
|
|
|
func TestAudioDuration(t *testing.T) {
|
|
t.Parallel()
|
|
// 16k mono int16 ⇒ 2 bytes/sample ⇒ 32000 bytes/second.
|
|
a := Audio{Format: PCM16kMono, Bytes: make([]byte, 32000)}
|
|
if got, want := a.Duration(), 1.0; got != want {
|
|
t.Fatalf("Duration: got %v, want %v", got, want)
|
|
}
|
|
// 4 seconds
|
|
a.Bytes = make([]byte, 128000)
|
|
if got, want := a.Duration(), 4.0; got != want {
|
|
t.Fatalf("Duration: got %v, want %v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestAudioDurationEmptyAndBad(t *testing.T) {
|
|
t.Parallel()
|
|
if (Audio{}).Duration() != 0 {
|
|
t.Fatalf("empty audio: Duration should be 0")
|
|
}
|
|
a := Audio{Format: Format{}, Bytes: make([]byte, 32000)}
|
|
if a.Duration() != 0 {
|
|
t.Fatalf("zero format: Duration should be 0")
|
|
}
|
|
a = Audio{Format: Format{SampleRate: 16000, Channels: 1, SampleBits: 16, Encoding: "opus"}, Bytes: make([]byte, 32000)}
|
|
if a.Duration() != 0 {
|
|
t.Fatalf("unsupported encoding: Duration should be 0")
|
|
}
|
|
}
|
|
|
|
func TestFormatIsValid(t *testing.T) {
|
|
t.Parallel()
|
|
if !PCM16kMono.IsValid() {
|
|
t.Fatalf("PCM16kMono should be valid")
|
|
}
|
|
if (Format{SampleRate: 8000, Channels: 1, SampleBits: 16, Encoding: "pcm_s16le"}).IsValid() {
|
|
t.Fatalf("8k should be rejected")
|
|
}
|
|
if (Format{SampleRate: 16000, Channels: 2, SampleBits: 16, Encoding: "pcm_s16le"}).IsValid() {
|
|
t.Fatalf("stereo should be rejected")
|
|
}
|
|
}
|
|
|
|
func TestWAVRoundTrip(t *testing.T) {
|
|
t.Parallel()
|
|
// 0.5s of square wave (alternating samples) — sndfile/aplay can play it.
|
|
const nsamp = 8000
|
|
pcm := make([]byte, nsamp*2)
|
|
for i := 0; i < nsamp; i++ {
|
|
var v int16 = -16384
|
|
if i%2 == 0 {
|
|
v = 16384
|
|
}
|
|
binary.LittleEndian.PutUint16(pcm[i*2:], uint16(v))
|
|
}
|
|
wav, err := WAVFromPCM(PCM16kMono, pcm)
|
|
if err != nil {
|
|
t.Fatalf("WAVFromPCM: %v", err)
|
|
}
|
|
if len(wav) != 44+len(pcm) {
|
|
t.Fatalf("wav length: got %d, want %d", len(wav), 44+len(pcm))
|
|
}
|
|
if string(wav[0:4]) != "RIFF" || string(wav[8:12]) != "WAVE" {
|
|
t.Fatalf("missing RIFF/WAVE marker: %q", wav[0:12])
|
|
}
|
|
f, pcm2, err := PCMFromWAV(wav)
|
|
if err != nil {
|
|
t.Fatalf("PCMFromWAV: %v", err)
|
|
}
|
|
if !f.IsValid() {
|
|
t.Fatalf("parsed format invalid: %+v", f)
|
|
}
|
|
if !bytes.Equal(pcm, pcm2) {
|
|
t.Fatalf("PCM mismatch after round-trip: in=%d bytes, out=%d bytes", len(pcm), len(pcm2))
|
|
}
|
|
}
|
|
|
|
func TestPCMFromWAVRejectsNonCanonical(t *testing.T) {
|
|
t.Parallel()
|
|
// too short
|
|
if _, _, err := PCMFromWAV([]byte("RIFF")); err == nil {
|
|
t.Fatalf("short input should error")
|
|
}
|
|
// bad RIFF marker
|
|
bad := make([]byte, 44)
|
|
copy(bad[0:4], []byte("RIFF"))
|
|
copy(bad[8:12], []byte("XXXX"))
|
|
if _, _, err := PCMFromWAV(bad); err == nil {
|
|
t.Fatalf("non-WAVE marker should error")
|
|
}
|
|
// format code 3 (float), canonical otherwise
|
|
wav, _ := WAVFromPCM(PCM16kMono, []byte{0, 0})
|
|
binary.LittleEndian.PutUint16(wav[20:22], 3) // IEEE float, not PCM
|
|
if _, _, err := PCMFromWAV(wav); err == nil {
|
|
t.Fatalf("non-PCM format should error")
|
|
}
|
|
}
|