--- name: voice-interface-builder description: Expert in building voice interfaces, speech recognition, and text-to-speech systems version: 1.0.0 tags: [voice, speech-recognition, text-to-speech, web-speech-api, accessibility] --- # Voice Interface Builder Skill I help you build voice-enabled interfaces using the Web Speech API and modern voice technologies. ## What I Do **Speech Recognition:** - Voice commands and controls - Voice-to-text input - Continuous dictation - Command detection **Text-to-Speech:** - Reading content aloud - Voice feedback and notifications - Multilingual speech output - Voice selection and customization **Voice UI:** - Voice-first interfaces - Accessibility features - Hands-free controls - Voice search ## Web Speech API Basics ### Speech Recognition ```typescript // hooks/useSpeechRecognition.ts 'use client' import { useState, useEffect, useRef } from 'react' interface SpeechRecognitionOptions { continuous?: boolean language?: string onResult?: (transcript: string) => void onError?: (error: string) => void } export function useSpeechRecognition({ continuous = false, language = 'en-US', onResult, onError }: SpeechRecognitionOptions = {}) { const [isListening, setIsListening] = useState(false) const [transcript, setTranscript] = useState('') const recognitionRef = useRef(null) useEffect(() => { if (typeof window === 'undefined') return const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition if (!SpeechRecognition) { console.warn('Speech recognition not supported') return } const recognition = new SpeechRecognition() recognition.continuous = continuous recognition.lang = language recognition.interimResults = true recognition.onresult = event => { const transcript = Array.from(event.results) .map(result => result[0].transcript) .join('') setTranscript(transcript) onResult?.(transcript) } recognition.onerror = event => { console.error('Speech recognition error:', event.error) onError?.(event.error) setIsListening(false) } recognition.onend = () => { setIsListening(false) } recognitionRef.current = recognition return () => { recognition.stop() } }, [continuous, language, onResult, onError]) const start = () => { if (recognitionRef.current && !isListening) { recognitionRef.current.start() setIsListening(true) } } const stop = () => { if (recognitionRef.current && isListening) { recognitionRef.current.stop() setIsListening(false) } } return { isListening, transcript, start, stop } } ``` **Usage:** ```typescript 'use client' import { useSpeechRecognition } from '@/hooks/useSpeechRecognition' export function VoiceInput() { const { isListening, transcript, start, stop } = useSpeechRecognition({ onResult: (text) => console.log('Recognized:', text) }) return (

{transcript}

) } ``` --- ### Text-to-Speech ```typescript // hooks/useSpeechSynthesis.ts 'use client' import { useState, useEffect } from 'react' export function useSpeechSynthesis() { const [voices, setVoices] = useState([]) const [speaking, setSpeaking] = useState(false) useEffect(() => { if (typeof window === 'undefined') return const loadVoices = () => { const availableVoices = window.speechSynthesis.getVoices() setVoices(availableVoices) } loadVoices() window.speechSynthesis.onvoiceschanged = loadVoices }, []) const speak = ( text: string, options?: { voice?: SpeechSynthesisVoice rate?: number pitch?: number volume?: number } ) => { if (typeof window === 'undefined') return const utterance = new SpeechSynthesisUtterance(text) if (options?.voice) utterance.voice = options.voice if (options?.rate) utterance.rate = options.rate // 0.1 - 10 if (options?.pitch) utterance.pitch = options.pitch // 0 - 2 if (options?.volume) utterance.volume = options.volume // 0 - 1 utterance.onstart = () => setSpeaking(true) utterance.onend = () => setSpeaking(false) utterance.onerror = () => setSpeaking(false) window.speechSynthesis.speak(utterance) } const cancel = () => { if (typeof window !== 'undefined') { window.speechSynthesis.cancel() setSpeaking(false) } } return { speak, cancel, speaking, voices } } ``` **Usage:** ```typescript 'use client' import { useSpeechSynthesis } from '@/hooks/useSpeechSynthesis' export function TextToSpeech() { const { speak, cancel, speaking, voices } = useSpeechSynthesis() const [text, setText] = useState('Hello, how can I help you today?') return (