feat(tts): Phase 4 — Read Page Aloud with OS-native voices
Platform-dispatched TTS (spd-say + espeak-ng fallback on Linux, say on macOS, PowerShell System.Speech on Windows) with a shared SpeakerButton component. Tap to speak, tap again to stop; only one button speaks at a time so two surfaces don't talk over each other. Text always travels via argv (or a PowerShell here-string delivered through -EncodedCommand on Windows) so user content never enters a shell string. Mount points: DictationPage transcript footer, transcript viewer header, per-step in MicroSteps. Settings gains a "Read aloud" accordion with voice picker (lazy-loaded from the OS synth), rate slider 0.5-2.0x, and a British-English test utterance. Rust tests cover rate mapping, NaN handling, and Windows here-string terminator safety. No pause/resume, no SSML, no cloud voices — that stays out of scope per the Layer-1 roadmap.
This commit is contained in:
@@ -71,6 +71,8 @@ const defaults: SettingsState = {
|
||||
microphoneDevice: "",
|
||||
currentEnergy: null,
|
||||
matchMyEnergy: false,
|
||||
ttsVoice: null,
|
||||
ttsRate: 1.0,
|
||||
};
|
||||
|
||||
function canUseStorage(): boolean {
|
||||
|
||||
10
src/lib/stores/speaker.svelte.ts
Normal file
10
src/lib/stores/speaker.svelte.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
// Phase 4 Read Page Aloud: tracks which SpeakerButton instance is
|
||||
// currently driving TTS. Only one speaker is active at a time — when
|
||||
// a second button starts speech, the first reverts its icon via the
|
||||
// `$derived` subscription in SpeakerButton.
|
||||
|
||||
export const activeSpeaker = $state<{ id: string | null }>({ id: null });
|
||||
|
||||
export function setActiveSpeaker(id: string | null): void {
|
||||
activeSpeaker.id = id;
|
||||
}
|
||||
Reference in New Issue
Block a user