소스 검색

recorder: add stereo pilot lock test

master
Jan Svabenik 1 일 전
부모
커밋
ca3be9f258
1개의 변경된 파일77개의 추가작업 그리고 0개의 파일을 삭제
  1. +77
    -0
      internal/recorder/streamer_test.go

+ 77
- 0
internal/recorder/streamer_test.go 파일 보기

@@ -0,0 +1,77 @@
package recorder

import (
"math"
"testing"
)

func TestStereoDecodeStatefulPilotLock(t *testing.T) {
const (
sampleRate = 192000
blockSize = 4096
blocks = 10
pilotAmp = 0.1
toneL = 440.0
toneR = 880.0
)

sess := &streamSession{}
var out []float32
locked := false

for b := 0; b < blocks; b++ {
mono := make([]float32, blockSize)
base := b * blockSize
for i := 0; i < blockSize; i++ {
t := float64(base+i) / float64(sampleRate)
l := math.Sin(2 * math.Pi * toneL * t)
r := math.Sin(2 * math.Pi * toneR * t)
lpr := 0.5 * (l + r)
lmr := 0.5 * (l - r)
composite := lpr + lmr*math.Cos(2*math.Pi*38000*t) + pilotAmp*math.Sin(2*math.Pi*19000*t)
mono[i] = float32(composite)
}
out, locked = sess.stereoDecodeStateful(mono, sampleRate)
}

if !locked {
t.Fatalf("expected pilot lock after warmup blocks")
}
if len(out) != blockSize*2 {
t.Fatalf("unexpected output size: got %d, want %d", len(out), blockSize*2)
}

left := make([]float32, blockSize)
right := make([]float32, blockSize)
for i := 0; i < blockSize; i++ {
left[i] = out[i*2]
right[i] = out[i*2+1]
}

magL440 := toneMagnitude(left, toneL, sampleRate)
magL880 := toneMagnitude(left, toneR, sampleRate)
magR440 := toneMagnitude(right, toneL, sampleRate)
magR880 := toneMagnitude(right, toneR, sampleRate)

if magL440 < 0.05 || magR880 < 0.05 {
t.Fatalf("decoded tones too weak: L440=%.3f R880=%.3f", magL440, magR880)
}
leftIsL := magL440 >= magL880*1.3 && magR880 >= magR440*1.3
rightIsL := magL880 >= magL440*1.3 && magR440 >= magR880*1.3
if !leftIsL && !rightIsL {
t.Fatalf(
"channels not cleanly separated: L440=%.3f L880=%.3f R440=%.3f R880=%.3f",
magL440, magL880, magR440, magR880,
)
}
}

func toneMagnitude(x []float32, freq float64, sampleRate int) float64 {
var iSum, qSum float64
for n, v := range x {
angle := 2 * math.Pi * freq * float64(n) / float64(sampleRate)
iSum += float64(v) * math.Cos(angle)
qSum += float64(v) * math.Sin(angle)
}
return math.Hypot(iSum, qSum) / float64(len(x))
}

불러오는 중...
취소
저장