feat(audio): passing tone only during races and remove legacy audio
Adds 'Calls during a race' (default: passing tone only, like timing systems) that drops name/personal best/leader/position calls in race sessions; practice keeps them. Removes the legacy audio panel and fallbacks, including its 'Sound on' switch that silently muted every race-audio voice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,9 +2,7 @@ import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
import {
|
||||
announcePassingHelper,
|
||||
announceRaceStartedHelper,
|
||||
getSessionAnnouncementText,
|
||||
handleSessionTimerTickHelper,
|
||||
selectSpeechVoice,
|
||||
speakTextHelper,
|
||||
@@ -21,48 +19,21 @@ test("speech voice selection prefers an explicit voice and then the current lang
|
||||
assert.equal(selectSpeechVoice(voices, "missing", "de-DE"), null);
|
||||
});
|
||||
|
||||
test("session announcements distinguish practice from racing", () => {
|
||||
const t = (key) => key;
|
||||
assert.equal(getSessionAnnouncementText({ type: "open_practice" }, "start", { t }), "timing.practice_started_voice");
|
||||
assert.equal(getSessionAnnouncementText({ type: "practice" }, "finish", { t }), "timing.practice_finished_voice");
|
||||
assert.equal(getSessionAnnouncementText({ type: "final" }, "start", { t }), "timing.race_started_voice");
|
||||
assert.equal(getSessionAnnouncementText({ type: "heat" }, "finish", { t }), "timing.race_finished_voice");
|
||||
});
|
||||
|
||||
test("passing announcement uses the driver's spoken name and beeps while speech is busy", () => {
|
||||
const calls = [];
|
||||
announcePassingHelper(
|
||||
{ displayName: "Anders", speechName: "Ann-ders" },
|
||||
{
|
||||
state: { settings: { audioEnabled: true, passingSoundMode: "name" } },
|
||||
t: () => "Unknown",
|
||||
speakText: (value, options) => { calls.push([value, options]); return false; },
|
||||
playPassingBeep: () => calls.push(["beep"]),
|
||||
}
|
||||
);
|
||||
|
||||
assert.deepEqual(calls, [["Ann-ders", { interrupt: false }], ["beep"]]);
|
||||
});
|
||||
|
||||
test("race start creates an overlay event and plays enabled start cues", async () => {
|
||||
test("race start only creates the overlay event - the old start tone and voice are gone (race audio owns the start)", async () => {
|
||||
const calls = [];
|
||||
announceRaceStartedHelper(
|
||||
{ id: "session_1", name: "A Final", type: "final" },
|
||||
{
|
||||
state: { settings: { audioEnabled: true, startSoundEnabled: true, finishVoiceEnabled: true } },
|
||||
// Old saved settings from the removed legacy panel must not bring the extra cues back.
|
||||
state: { settings: { audioEnabled: true, startSoundEnabled: true, finishVoiceEnabled: true, raceAudio: { enabled: false } } },
|
||||
t: (key) => key,
|
||||
pushOverlayEvent: (type, label, options) => calls.push([type, label, options]),
|
||||
playStartCue: () => calls.push(["tone"]),
|
||||
speakText: (value, options) => calls.push(["speech", value, options]),
|
||||
}
|
||||
);
|
||||
|
||||
assert.deepEqual(calls, [
|
||||
["start", "A Final • timing.start", { silentCue: true }],
|
||||
["tone"],
|
||||
]);
|
||||
await new Promise((resolve) => setTimeout(resolve, 700));
|
||||
assert.deepEqual(calls[2], ["speech", "timing.race_started_voice", { interrupt: true }]);
|
||||
assert.deepEqual(calls, [["start", "A Final • timing.start", { silentCue: true }]]);
|
||||
});
|
||||
|
||||
test("session timer emits each race-audio clock marker once without changing finish rules", () => {
|
||||
@@ -111,8 +82,10 @@ test("race audio can ignore a mismatched configured voice and select the announc
|
||||
constructor(text) { this.text = text; }
|
||||
};
|
||||
try {
|
||||
// audioEnabled false: the removed legacy "Sound on" switch used to silence every race-audio
|
||||
// voice (while effects still played). It must no longer have any effect.
|
||||
const started = speakTextHelper("Race finished", {
|
||||
state: { settings: { audioEnabled: true, speechVoiceUri: "voice-sv", speechRate: 1, speechPitch: 1 } },
|
||||
state: { settings: { audioEnabled: false, speechVoiceUri: "voice-sv", speechRate: 1, speechPitch: 1 } },
|
||||
currentLanguage: () => "sv",
|
||||
}, { language: "en", voiceUri: "", rate: 1.1, pitch: 0.85 });
|
||||
assert.equal(started, true);
|
||||
|
||||
Reference in New Issue
Block a user