feat(audio): choose a male or female local voice per language
The installer now fetches one male and one female Piper voice per language (Swedish NST/Lisa, English Ryan/Lessac), with genders confirmed by measuring each voice's pitch rather than guessed from the name. Settings -> Audio gets a voice selector per language with its own Test button that always plays the Piper voice. Male is preselected for both. The integration test now runs its server with an empty home directory, so voices installed on the developer's own machine can't leak into it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -134,6 +134,8 @@ export function applyPersistedStateHelper(persisted, deps) {
|
||||
speechRate: Math.max(0.65, Math.min(1.35, Number(persisted.settings?.speechRate || state.settings.speechRate || 0.95) || 0.95)),
|
||||
speechPitch: Math.max(0.7, Math.min(1.3, Number(persisted.settings?.speechPitch || state.settings.speechPitch || 1) || 1)),
|
||||
ttsEngine: persisted.settings?.ttsEngine === "piper" ? "piper" : "browser",
|
||||
ttsVoiceSv: String(persisted.settings?.ttsVoiceSv || ""),
|
||||
ttsVoiceEn: String(persisted.settings?.ttsVoiceEn || ""),
|
||||
speakerPassingCueEnabled: persisted.settings?.speakerPassingCueEnabled === true,
|
||||
speakerLeaderCueEnabled: persisted.settings?.speakerLeaderCueEnabled !== false,
|
||||
speakerFinishCueEnabled: persisted.settings?.speakerFinishCueEnabled !== false,
|
||||
@@ -368,8 +370,10 @@ export function getSessionAnnouncementText(session, phase, { t }) {
|
||||
export function speakTextHelper(text, { state, currentLanguage }, options = {}) {
|
||||
if (!state.settings.audioEnabled || !text) return false;
|
||||
if (state.settings.ttsEngine === "piper" && !options.skipPiper) {
|
||||
const piperLanguage = String(options.language || currentLanguage()).toLowerCase().startsWith("sv") ? "sv" : "en";
|
||||
return speakWithPiper(text, {
|
||||
language: String(options.language || currentLanguage()).toLowerCase().startsWith("sv") ? "sv" : "en",
|
||||
language: piperLanguage,
|
||||
voice: piperLanguage === "sv" ? state.settings.ttsVoiceSv : state.settings.ttsVoiceEn,
|
||||
rate: Math.max(0.65, Math.min(1.35, Number(options.rate ?? state.settings.speechRate ?? 0.95) || 0.95)),
|
||||
volume: options.volume ?? 1,
|
||||
interrupt: options.interrupt,
|
||||
|
||||
Reference in New Issue
Block a user