93 lines
2.6 KiB
TypeScript
93 lines
2.6 KiB
TypeScript
import { type BarkBattleSession, createBarkBattleSession } from '../domain/BarkBattleSession';
|
|
import type { MicrophoneFailureReason } from '../domain/BarkBattleTypes';
|
|
import { BarkDetector } from '../domain/BarkDetector';
|
|
import type { BarkBattleConfig } from './BarkBattleConfig';
|
|
|
|
export class BarkBattleController {
|
|
private session: BarkBattleSession;
|
|
private detector: BarkDetector;
|
|
private sampleClockMs = 0;
|
|
|
|
constructor(private config: BarkBattleConfig) {
|
|
this.session = createBarkBattleSession(config);
|
|
this.detector = this.createDetector();
|
|
}
|
|
|
|
getSnapshot() {
|
|
return this.session.snapshot;
|
|
}
|
|
|
|
getSampleClockMs() {
|
|
return this.sampleClockMs;
|
|
}
|
|
|
|
updateConfig(config: BarkBattleConfig) {
|
|
this.config = config;
|
|
this.restart();
|
|
}
|
|
|
|
finishNow() {
|
|
if (this.session.snapshot.phase !== 'playing') {
|
|
this.session = this.session.startMockRound();
|
|
}
|
|
if (this.session.snapshot.phase === 'countdown') {
|
|
this.session = this.session.tick(this.session.snapshot.countdownMs);
|
|
}
|
|
this.session = this.session.tick(this.session.snapshot.remainingMs + 1);
|
|
}
|
|
|
|
startWithMockInput() {
|
|
this.session = createBarkBattleSession(this.config).startMockRound();
|
|
this.detector = this.createDetector();
|
|
this.sampleClockMs = 0;
|
|
}
|
|
|
|
forcePlayerBark(volume = 0.9) {
|
|
if (this.session.snapshot.phase !== 'playing') {
|
|
this.session = this.session.startMockRound();
|
|
}
|
|
if (this.session.snapshot.phase === 'countdown') {
|
|
this.session = this.session.tick(this.session.snapshot.countdownMs);
|
|
}
|
|
this.session = this.session.applyPlayerBark({
|
|
side: 'player',
|
|
atMs: this.sampleClockMs,
|
|
peakVolume: volume,
|
|
durationMs: this.config.minBarkDurationMs,
|
|
});
|
|
}
|
|
|
|
submitInputSample(volume: number, atMs = this.sampleClockMs) {
|
|
const events = this.detector.acceptSample({ atMs, volume });
|
|
for (const event of events) {
|
|
this.session = this.session.applyPlayerBark(event);
|
|
}
|
|
}
|
|
|
|
submitMockSample(volume: number) {
|
|
this.submitInputSample(volume);
|
|
}
|
|
|
|
tick(deltaMs: number) {
|
|
this.sampleClockMs += deltaMs;
|
|
this.session = this.session.tick(deltaMs);
|
|
}
|
|
|
|
restart() {
|
|
this.session = createBarkBattleSession(this.config);
|
|
this.detector = this.createDetector();
|
|
this.sampleClockMs = 0;
|
|
}
|
|
|
|
failMicrophone(reason: MicrophoneFailureReason) {
|
|
this.session = this.session.failMicrophone(reason);
|
|
}
|
|
|
|
private createDetector() {
|
|
return new BarkDetector({
|
|
threshold: this.config.barkThreshold,
|
|
minBarkGapMs: this.config.minBarkGapMs,
|
|
});
|
|
}
|
|
}
|