feat(audio): add offline local neural voice via Piper (sv + en)
Announcements can use Piper, a free local neural TTS, instead of the browser's system voice. No account, no paid service, and it keeps working with no internet at the track. - npm run tts:install (or Settings -> Audio -> Install) downloads the standalone Piper release for Linux/Windows/macOS plus Swedish and English voices into piper/ once - server/tts.js generates each line once, one at a time, and caches it as WAV under data/tts/; a new line takes ~0.3 s with the standalone build - src/piper_speech.js plays it and falls back to the browser voice if Piper is missing, errors, or takes over 2.5 s, so no announcement is lost and timing is never held up - "Pre-generate phrases and driver names" renders every fixed phrase and name in both languages before race day Browser voice stays the default. Generation routes fall under the admin PIN. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { decoderDiagnosticsMarkup, mountDecoderDiagnostics } from "./decoder_diagnostics_view.js";
|
||||
import { mountAuthSettings } from "./auth_view.js";
|
||||
import { mountTtsSettings } from "./tts_settings_view.js";
|
||||
|
||||
let activeSettingsTab = "connection";
|
||||
|
||||
@@ -233,6 +234,10 @@ export function renderSettings(deps) {
|
||||
</div>
|
||||
|
||||
<div data-settings-panel="audio">
|
||||
<section class="panel mt-16">
|
||||
<div class="panel-header"><h3>${t("tts.title")}</h3></div>
|
||||
<div class="panel-body" id="ttsSettings"></div>
|
||||
</section>
|
||||
<section class="panel mt-16">
|
||||
<div class="panel-header"><h3>${t("audio.race_sounds")}</h3></div>
|
||||
<div class="panel-body form-grid cols-4 settings-grid settings-grid-toggles">
|
||||
@@ -641,6 +646,7 @@ Erik Eriksson;654321;4WD;Associated;;</code></pre>
|
||||
});
|
||||
applySettingsTab(settingsTabButtons.some((button) => button.dataset.settingsTab === activeSettingsTab) ? activeSettingsTab : "connection");
|
||||
mountAuthSettings(document.getElementById("authSettings"), { t, escapeHtml });
|
||||
mountTtsSettings(document.getElementById("ttsSettings"), { state, t, escapeHtml, saveState, speakText });
|
||||
|
||||
const applyRaceAudioFormValues = (form) => {
|
||||
const events = {};
|
||||
|
||||
Reference in New Issue
Block a user