feat: add bark battle browser prototype

This commit is contained in:
2026-05-11 18:01:55 +08:00
parent bf72c2e48d
commit 2b046656dc
32 changed files with 2244 additions and 18 deletions

View File

@@ -0,0 +1,62 @@
import { describe, expect, it } from 'vitest';
import { DEFAULT_BARK_BATTLE_CONFIG } from '../../application/BarkBattleConfig';
import { BarkDetector } from '../BarkDetector';
describe('BarkDetector', () => {
it('超过阈值且持续时长合规时只计为一次有效叫声', () => {
const detector = new BarkDetector({
threshold: 0.45,
minBarkGapMs: DEFAULT_BARK_BATTLE_CONFIG.minBarkGapMs,
minBarkDurationMs: 90,
maxBarkDurationMs: 900,
});
expect(detector.acceptSample({ atMs: 0, volume: 0.2 })).toEqual([]);
expect(detector.acceptSample({ atMs: 40, volume: 0.72 })).toEqual([]);
expect(detector.acceptSample({ atMs: 150, volume: 0.76 })).toEqual([]);
const events = detector.acceptSample({ atMs: 180, volume: 0.2 });
expect(events).toHaveLength(1);
expect(events[0]).toMatchObject({ side: 'player', peakVolume: 0.76 });
expect(events[0]?.durationMs).toBe(140);
});
it('持续噪音不会在每个 tick 无限计数', () => {
const detector = new BarkDetector({
threshold: 0.4,
minBarkGapMs: 250,
minBarkDurationMs: 80,
maxBarkDurationMs: 600,
});
const allEvents = [
...detector.acceptSample({ atMs: 0, volume: 0.7 }),
...detector.acceptSample({ atMs: 100, volume: 0.72 }),
...detector.acceptSample({ atMs: 200, volume: 0.73 }),
...detector.acceptSample({ atMs: 300, volume: 0.75 }),
...detector.acceptSample({ atMs: 500, volume: 0.2 }),
];
expect(allEvents).toHaveLength(1);
});
it('低于阈值的背景噪音、过短脉冲和冷却内峰值不计数', () => {
const detector = new BarkDetector({
threshold: 0.5,
minBarkGapMs: 300,
minBarkDurationMs: 80,
maxBarkDurationMs: 800,
});
expect(detector.acceptSample({ atMs: 0, volume: 0.48 })).toEqual([]);
detector.acceptSample({ atMs: 20, volume: 0.9 });
expect(detector.acceptSample({ atMs: 60, volume: 0.2 })).toEqual([]);
detector.acceptSample({ atMs: 500, volume: 0.88 });
expect(detector.acceptSample({ atMs: 620, volume: 0.2 })).toHaveLength(1);
detector.acceptSample({ atMs: 700, volume: 0.9 });
expect(detector.acceptSample({ atMs: 820, volume: 0.2 })).toEqual([]);
});
});