# TTS Providers Overview

> Compare Text-to-Speech providers for voice quality, latency, language support, and cost to create natural-sounding voice agents.

Source: https://edesy.in/docs/voice-agent/tts

Text-to-Speech (TTS) converts the LLM's response into natural-sounding audio. The right TTS provider creates a seamless, human-like conversation experience.

## Supported Providers

| Provider | Quality | Latency | Languages | Best For |
|----------|---------|---------|-----------|----------|
| [Cartesia](https://edesy.in/docs/voice-agent/tts/cartesia) | ⭐⭐⭐⭐⭐ | ⚡ Fastest | 50+ | Low-latency voice agents |
| [ElevenLabs](https://edesy.in/docs/voice-agent/tts/elevenlabs) | ⭐⭐⭐⭐⭐ | 🚀 Fast | 30+ | Premium voice quality |
| [Google](https://edesy.in/docs/voice-agent/tts/google) | ⭐⭐⭐⭐ | 🚀 Fast | 50+ | Multilingual |
| [Azure](https://edesy.in/docs/voice-agent/tts/azure) | ⭐⭐⭐⭐⭐ | 🚀 Fast | 100+ | Enterprise + Indic |
| [OpenAI](https://edesy.in/docs/voice-agent/tts/openai) | ⭐⭐⭐⭐ | 🚀 Fast | 57+ | Simple integration |
| [Deepgram](https://edesy.in/docs/voice-agent/tts/deepgram) | ⭐⭐⭐⭐ | ⚡ Fastest | 30+ | Aura voices |

## Quick Comparison

```
Time to First Audio Chunk (lower is better):
──────────────────────────────────────────────────────────────────

Cartesia Sonic    ████░░░░░░░░░░░░░░░░░░░░░░░░░░░░  50ms
Deepgram Aura     ████░░░░░░░░░░░░░░░░░░░░░░░░░░░░  60ms
Google WaveNet    ██████████░░░░░░░░░░░░░░░░░░░░░░  100ms
Azure Neural      ████████████░░░░░░░░░░░░░░░░░░░░  120ms
ElevenLabs        ████████████████░░░░░░░░░░░░░░░░  150ms
OpenAI TTS        ██████████████████░░░░░░░░░░░░░░  180ms

                  0ms              100ms            200ms
```

## Choosing the Right Provider

### For Low Latency (Recommended)

**Cartesia Sonic**

- Fastest time-to-first-audio (~50ms)
- High-quality neural voices
- Excellent streaming support
- Optimized for real-time

```json
{
  "ttsProvider": "cartesia",
  "ttsVoice": "95856005-0332-41b0-935f-352e296aa0df"
}
```

### For Premium Quality

**ElevenLabs**

- Most natural-sounding voices
- Emotion and style control
- Voice cloning available
- Best for premium experiences

```json
{
  "ttsProvider": "elevenlabs",
  "ttsVoice": "21m00Tcm4TlvDq8ikWAM"
}
```

### For Indic Languages

**Azure Neural**

- Best quality for Hindi, Tamil, Telugu, Bengali
- Excellent Assamese support
- Regional accent options

```json
{
  "ttsProvider": "azure",
  "ttsVoice": "hi-IN-SwaraNeural"
}
```

### For Enterprise

**Azure Neural** or **Google WaveNet**

- Enterprise SLAs
- Data residency options
- Custom voice training
- SOC 2, HIPAA compliant

## Streaming Architecture

TTS streaming is critical for low latency:

```
Non-Streaming (Slow):
─────────────────────────────────────────────────────────────
LLM: "Your order has been shipped..."
      │
      └── Wait for complete text ──────────────────────────┐
                                                           │
TTS: ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ [Generate all] ──┤
                                                           │
Audio: ────────────────────────────── [Play all at once] ──┘
Total: 500ms+ delay

Streaming (Fast):
─────────────────────────────────────────────────────────────
LLM:   "Your" → "order" → "has" → "been" → "shipped..."
         │        │        │        │         │
TTS:    [Gen]    [Gen]    [Gen]    [Gen]     [Gen]
         │        │        │        │         │
Audio:  [Play]   [Play]   [Play]   [Play]    [Play]
         └─── 50ms ──┘
```

### Implementation

```go
// Stream TTS as LLM tokens arrive
func streamTTS(llmOutput <-chan string, audioOutput chan<- []byte) {
    var buffer strings.Builder

    for token := range llmOutput {
        buffer.WriteString(token)

        // Flush buffer at sentence boundaries
        if endsWithPunctuation(buffer.String()) {
            text := buffer.String()
            buffer.Reset()

            // Stream audio chunks
            for chunk := range tts.StreamSynthesize(text) {
                audioOutput <- chunk
            }
        }
    }

    // Flush remaining text
    if buffer.Len() > 0 {
        for chunk := range tts.StreamSynthesize(buffer.String()) {
            audioOutput <- chunk
        }
    }
}
```

## Audio Specifications

| Parameter | Requirement | Notes |
|-----------|-------------|-------|
| Sample Rate | 8000 Hz | Telephony (μ-law) |
| Channels | Mono | Single channel |
| Bit Depth | 16-bit | Linear PCM |
| Output | μ-law or PCM | Provider dependent |

### Audio Conversion for Telephony

```go
// TTS outputs 24kHz, telephony needs 8kHz μ-law
func convertForTelephony(input []byte, inputRate int) []byte {
    // Downsample to 8kHz
    resampled := downsample(input, inputRate, 8000)

    // Convert to μ-law
    mulaw := pcmToMulaw(resampled)

    return mulaw
}
```

## Voice Selection Guide

### By Use Case

| Use Case | Recommended Voice Type |
|----------|----------------------|
| Customer Support | Warm, friendly, moderate pace |
| Sales | Energetic, confident |
| Healthcare | Calm, clear, reassuring |
| Banking | Professional, trustworthy |
| Entertainment | Dynamic, expressive |

### Voice Characteristics

```go
type VoiceProfile struct {
    Gender     string   // male, female, neutral
    Age        string   // young, adult, senior
    Tone       string   // warm, professional, casual
    Pace       string   // slow, moderate, fast
    Pitch      string   // low, medium, high
    Languages  []string // Supported languages
}

// Example profiles
var SupportVoice = VoiceProfile{
    Gender: "female",
    Age:    "adult",
    Tone:   "warm",
    Pace:   "moderate",
    Pitch:  "medium",
}
```

## Cost Comparison

| Provider | Cost per 1K chars | Monthly (10M chars) |
|----------|-------------------|---------------------|
| Cartesia | $0.015 | $150 |
| Deepgram | $0.015 | $150 |
| Google WaveNet | $0.016 | $160 |
| Azure Neural | $0.016 | $160 |
| OpenAI TTS | $0.015 | $150 |
| ElevenLabs | $0.18 | $1,800 |

## SSML Support

Speech Synthesis Markup Language for fine control:

```xml
<!-- Pause -->
<speak>
  Your order number is <break time="500ms"/> 1 2 3 4 5.
</speak>

<!-- Pronunciation -->
<speak>
  <phoneme alphabet="ipa" ph="ˈɛdəsi">Edesy</phoneme>
  helps you build voice agents.
</speak>

<!-- Emphasis -->
<speak>
  Your order is <emphasis level="strong">confirmed</emphasis>.
</speak>

<!-- Prosody (speed, pitch, volume) -->
<speak>
  <prosody rate="slow" pitch="+5%">
    Please speak clearly after the beep.
  </prosody>
</speak>
```

### Provider SSML Support

| Feature | Cartesia | ElevenLabs | Google | Azure |
|---------|----------|------------|--------|-------|
| Pauses | ✅ | ✅ | ✅ | ✅ |
| Pronunciation | ❌ | ❌ | ✅ | ✅ |
| Emphasis | ❌ | ✅ | ✅ | ✅ |
| Prosody | ❌ | ✅ | ✅ | ✅ |
| Say-as (dates, numbers) | ❌ | ❌ | ✅ | ✅ |

## Caching Strategy

Cache frequently used phrases:

```go
type TTSCache struct {
    cache map[string][]byte
    mu    sync.RWMutex
}

func (c *TTSCache) GetOrGenerate(text string, voice string) []byte {
    key := fmt.Sprintf("%s:%s", voice, hash(text))

    c.mu.RLock()
    if audio, ok := c.cache[key]; ok {
        c.mu.RUnlock()
        return audio
    }
    c.mu.RUnlock()

    // Generate and cache
    audio := tts.Synthesize(text, voice)

    c.mu.Lock()
    c.cache[key] = audio
    c.mu.Unlock()

    return audio
}

// Pre-cache common phrases
func preCacheGreetings(agent *Agent) {
    phrases := []string{
        agent.GreetingMessage,
        "One moment please.",
        "I'm looking that up for you.",
        "Is there anything else I can help with?",
        "Thank you for calling. Goodbye!",
    }

    for _, phrase := range phrases {
        cache.GetOrGenerate(phrase, agent.TTSVoice)
    }
}
```

## Error Handling

```go
func (t *TTS) synthesizeWithFallback(text string) ([]byte, error) {
    // Try primary provider
    audio, err := t.primary.Synthesize(text)
    if err == nil {
        return audio, nil
    }

    log.Printf("Primary TTS failed: %v, trying fallback", err)

    // Try fallback provider
    audio, err = t.fallback.Synthesize(text)
    if err != nil {
        return nil, fmt.Errorf("all TTS providers failed: %w", err)
    }

    return audio, nil
}
```

## Next Steps

- [Cartesia Configuration](https://edesy.in/docs/voice-agent/tts/cartesia) - Fastest TTS
- [ElevenLabs Configuration](https://edesy.in/docs/voice-agent/tts/elevenlabs) - Premium quality
- [Azure Configuration](https://edesy.in/docs/voice-agent/tts/azure) - Enterprise + Indic
- [Voice Selection Guide](https://edesy.in/docs/voice-agent/api/provider-catalog) - Choose the right voice
