Skip to main contentSkip to navigation

AI Voice Settings

Composable voice configuration components for AI voice interfaces with language, voice, personality, and audio settings

Component ai-voice-settings-demo not found in registry.

Overview

AI Voice Settings provides a comprehensive, composable configuration interface for voice AI applications. Built with orthogonal design principles, each setting component can be used independently or combined in the full settings interface.

Architecture: Composability First

This component follows the "more is more" philosophy with a highly modular architecture:

9 Independent Sub-Components

Each component is orthogonal (independent, single-purpose) and can be composed as needed:

  1. VoiceSelector - Voice selection with gender badges
  2. LanguageSelector - Language selection with auto-detect
  3. PersonalitySelector - Personality/tone selection
  4. SpeedControl - Speaking speed slider (0.5x - 2.0x)
  5. PitchControl - Voice pitch slider (0.5x - 2.0x)
  6. WakeWordInput - Wake word configuration
  7. CustomInstructions - AI instructions textarea
  8. AutoListenToggle - Auto-listen mode toggle
  9. NoiseCancellationToggle - Noise cancellation toggle

Benefits of Composability

  • ✅ Use only what you need
  • ✅ Mix and match components
  • ✅ Create custom layouts
  • ✅ Consistent API across components
  • ✅ Easy to extend and customize

Usage

Full Settings Interface

The complete settings component with all features:

import { AIVoiceSettings } from "@/components/ui/ai-voice-settings"

export default function Settings() {
  const handleSave = (settings) => {
    // Save to localStorage, database, etc.
    localStorage.setItem("voiceSettings", JSON.stringify(settings))
  }

  return (
    <AIVoiceSettings
      settings={{
        voice: "nova",
        language: "en-US",
        personality: "friendly",
        speed: 1.0,
        pitch: 1.0,
        wakeWord: "Hey Assistant",
        customInstructions: "",
        autoListen: false,
        noiseCancellation: true,
      }}
      onSettingsChange={(settings) => console.log(settings)}
      onSave={handleSave}
      onPreview={(voice, speed, pitch) => {
        // Play preview audio
      }}
    />
  )
}

Using Individual Components

The power of composability - use components independently:

Voice Selector Only

import { VoiceSelector } from "@/components/ui/ai-voice-settings"

export default function QuickVoiceSelect() {
  const [voice, setVoice] = useState("alloy")

  return <VoiceSelector value={voice} onValueChange={setVoice} />
}

Language + Voice Combo

import {
  LanguageSelector,
  VoiceSelector,
} from "@/components/ui/ai-voice-settings"

export default function LanguageAndVoice() {
  const [language, setLanguage] = useState("en-US")
  const [voice, setVoice] = useState("nova")

  return (
    <div className="space-y-4">
      <LanguageSelector value={language} onValueChange={setLanguage} />
      <VoiceSelector value={voice} onValueChange={setVoice} />
    </div>
  )
}

Speed & Pitch Controls

import { PitchControl, SpeedControl } from "@/components/ui/ai-voice-settings"

export default function VoiceCharacteristics() {
  const [speed, setSpeed] = useState(1.0)
  const [pitch, setPitch] = useState(1.0)

  return (
    <div className="space-y-6">
      <SpeedControl value={speed} onValueChange={setSpeed} />
      <PitchControl value={pitch} onValueChange={setPitch} />
    </div>
  )
}

Custom Layout

Build your own layout with any combination:

import {
  AutoListenToggle,
  PersonalitySelector,
  SpeedControl,
  VoiceSelector,
} from "@/components/ui/ai-voice-settings"

export default function CustomSettings() {
  return (
    <Card>
      <CardHeader>
        <CardTitle>Quick Voice Setup</CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        <VoiceSelector value={voice} onValueChange={setVoice} />
        <PersonalitySelector
          value={personality}
          onValueChange={setPersonality}
        />
        <SpeedControl value={speed} onValueChange={setSpeed} />
        <AutoListenToggle
          checked={autoListen}
          onCheckedChange={setAutoListen}
        />
      </CardContent>
    </Card>
  )
}

Component API

AIVoiceSettings (Main Component)

PropTypeDescription
settingsPartial<AIVoiceSettings>Initial settings object
onSettingsChange(settings: AIVoiceSettings) => voidCalled when any setting changes
onSave(settings: AIVoiceSettings) => voidCalled when Save button clicked
onReset() => voidCalled when Reset button clicked
onPreview(voice: string, speed: number, pitch: number) => voidCalled when Preview button clicked

VoiceSelector

PropTypeDefaultDescription
valuestring-Current voice value
onValueChange(value: string) => void-Change handler
voicesVoice[]Built-in voicesCustom voice list
showDescriptionbooleantrueShow voice description

LanguageSelector

PropTypeDefaultDescription
valuestring-Current language value
onValueChange(value: string) => void-Change handler
languagesLanguage[]Built-in languagesCustom language list
showAutoDetectbooleantrueShow auto-detect option

PersonalitySelector

PropTypeDefaultDescription
valuestring-Current personality value
onValueChange(value: string) => void-Change handler
personalitiesPersonality[]Built-in personalitiesCustom personality list
showDescriptionbooleantrueShow personality description

SpeedControl

PropTypeDefaultDescription
valuenumber-Current speed (0.5 - 2.0)
onValueChange(value: number) => void-Change handler
minnumber0.5Minimum speed
maxnumber2.0Maximum speed
stepnumber0.1Step increment

PitchControl

PropTypeDefaultDescription
valuenumber-Current pitch (0.5 - 2.0)
onValueChange(value: number) => void-Change handler
minnumber0.5Minimum pitch
maxnumber2.0Maximum pitch
stepnumber0.1Step increment

WakeWordInput

PropTypeDefaultDescription
valuestring-Current wake word
onValueChange(value: string) => void-Change handler
placeholderstringDefault messageInput placeholder

CustomInstructions

PropTypeDefaultDescription
valuestring-Current instructions
onValueChange(value: string) => void-Change handler
rowsnumber4Textarea rows
placeholderstringDefault messageTextarea placeholder

AutoListenToggle

PropTypeDescription
checkedbooleanToggle state
onCheckedChange(checked: boolean) => voidChange handler

NoiseCancellationToggle

PropTypeDescription
checkedbooleanToggle state
onCheckedChange(checked: boolean) => voidChange handler

Built-in Data

Voices (8 options)

const voices = [
  {
    label: "Alloy",
    value: "alloy",
    gender: "neutral",
    description: "Neutral and balanced",
  },
  {
    label: "Echo",
    value: "echo",
    gender: "male",
    description: "Clear and articulate",
  },
  {
    label: "Fable",
    value: "fable",
    gender: "neutral",
    description: "Expressive storytelling",
  },
  {
    label: "Onyx",
    value: "onyx",
    gender: "male",
    description: "Deep and authoritative",
  },
  {
    label: "Nova",
    value: "nova",
    gender: "female",
    description: "Warm and friendly",
  },
  {
    label: "Shimmer",
    value: "shimmer",
    gender: "female",
    description: "Energetic and bright",
  },
  {
    label: "Samantha",
    value: "samantha",
    gender: "female",
    description: "Classic and smooth",
  },
  { label: "Alex", value: "alex", gender: "male", description: "Professional" },
]

Languages (20+ options)

Includes English (US, UK, AU), Spanish, French, German, Italian, Portuguese, Japanese, Korean, Chinese, Arabic, Hindi, Russian, Dutch, Polish, and more.

Personalities (5 options)

  • Friendly - Warm and approachable
  • Professional - Formal and authoritative
  • Enthusiastic - Energetic and upbeat
  • Calm - Soothing and measured
  • Witty - Quick and clever

Custom Data

Provide your own data for any selector:

// Custom voices
const customVoices = [
  { label: "Jarvis", value: "jarvis", gender: "male", description: "AI assistant" },
  { label: "Friday", value: "friday", gender: "female", description: "AI companion" },
]

<VoiceSelector
  value={voice}
  onValueChange={setVoice}
  voices={customVoices}
/>

// Custom personalities
const customPersonalities = [
  { label: "Helpful", value: "helpful", description: "Always ready to assist" },
  { label: "Creative", value: "creative", description: "Thinks outside the box" },
]

<PersonalitySelector
  value={personality}
  onValueChange={setPersonality}
  personalities={customPersonalities}
/>

Integration Examples

Save to LocalStorage

const handleSave = (settings: AIVoiceSettings) => {
  localStorage.setItem("hanzo-voice-settings", JSON.stringify(settings))
  toast.success("Settings saved!")
}

const loadSettings = () => {
  const saved = localStorage.getItem("hanzo-voice-settings")
  return saved ? JSON.parse(saved) : undefined
}

;<AIVoiceSettings settings={loadSettings()} onSave={handleSave} />

Integrate with AI Voice Component

import { AIVoice } from "@/components/ui/ai-voice"
import { AIVoiceSettings } from "@/components/ui/ai-voice-settings"

export default function VoiceChat() {
  const [settings, setSettings] = useState(defaultSettings)

  return (
    <div className="grid gap-4">
      {/* Voice interaction */}
      <AIVoice
        language={settings.language}
        voice={{
          id: settings.voice,
          speed: settings.speed,
          pitch: settings.pitch,
        }}
        wakeWord={settings.wakeWord}
        autoStart={settings.autoListen}
        onTranscript={handleTranscript}
      />

      {/* Settings panel */}
      <AIVoiceSettings settings={settings} onSettingsChange={setSettings} />
    </div>
  )
}

Preview Voice

const handlePreview = async (voice: string, speed: number, pitch: number) => {
  const utterance = new SpeechSynthesisUtterance(
    "Hello, this is how I sound with these settings."
  )
  utterance.voice = speechSynthesis.getVoices().find((v) => v.name === voice)
  utterance.rate = speed
  utterance.pitch = pitch
  speechSynthesis.speak(utterance)
}

;<AIVoiceSettings onPreview={handlePreview} />

Styling

All components inherit theme colors and adapt to light/dark mode. Customize with className:

<VoiceSelector
  className="border-2 rounded-xl"
  value={voice}
  onValueChange={setVoice}
/>

Accessibility

  • All form inputs have proper labels
  • Keyboard navigation support
  • Screen reader friendly
  • ARIA attributes where appropriate
  • Focus indicators
  • High contrast mode support

Best Practices

  1. Start Simple: Use individual components for focused UIs
  2. Compose Up: Build complex settings from simple pieces
  3. Persist Settings: Save user preferences
  4. Provide Feedback: Show when settings are saved
  5. Test Thoroughly: Verify voice preview works across browsers
  6. Handle Errors: Gracefully handle unsupported voices/languages