Integrations

Pipecat

SonexTTSService is a Pipecat TTSService that drives SonexLabs Pāṇini TTS over HTTP. It works with any Pipecat transport — SmallWebRTC, FastAPI WebSocket, Twilio, Exotel, Vobiz — no Daily required.

Install

pip install pipecat-ai pipecat-sonex

Requires Python 3.10+ and pipecat-ai≥1.1.0.

Basic usage

import os
from pipecat_sonex import SonexTTSService

tts = SonexTTSService(
    api_key=os.getenv("SONEX_API_KEY"),   # vsk_...
    voice="VOICE_ID",                      # from GET /v1/voices
    language="en",                         # BCP-47 or "" for auto-detect
)

# Drop into any pipeline — no transport dependency
pipeline = Pipeline([..., llm, tts, transport.output()])

Configuration

api_keystrRequired

SonexLabs API key (vsk_...). Falls back to SONEX_API_KEY env var.

voicestrRequired

Voice ID from GET /v1/voices. Use "auto" for the server default.

languagestrOptional

BCP-47 language tag (e.g. "en", "hi-IN"). Empty = auto-detect.

speedfloatOptional

Speaking rate multiplier. Range 0.5–2.0. Default 1.0.

sample_rateintOptional

Output audio sample rate in Hz. Default 24000. Use 8000 for telephony.

How it works

The processor buffers LLMTextFrame tokens until a sentence boundary, then:

  1. POSTs { "input": "...", "voice": "...", "response_format": "wav" } to the Pāṇini TTS endpoint
  2. Releases the inference lock at TTFB — the GPU is free and the next sentence can start immediately
  3. Downloads the full WAV body, parses the PCM data chunk from the WAV header
  4. Pushes TTSAudioRawFrame frames at 24 kHz downstream to the transport

It also handles TTSSpeakFrame for direct synthesis, strips markdown formatting, skips non-speakable tokens, and rotates across multiple endpoints for load balancing.

Full pipeline example (WebRTC)

import os, asyncio
from pipecat.pipeline.pipeline import Pipeline
from pipecat.pipeline.runner import PipelineRunner
from pipecat.pipeline.task import PipelineParams, PipelineTask
from pipecat.services.groq.llm import GroqLLMService
from pipecat.audio.vad.silero import SileroVADAnalyzer
from pipecat.transports.base_transport import TransportParams
from pipecat.transports.smallwebrtc.transport import SmallWebRTCTransport
from pipecat_sonex import SonexTTSService

async def run_bot(webrtc_connection, stt):
    transport = SmallWebRTCTransport(
        webrtc_connection,
        params=TransportParams(
            audio_in_enabled=True,
            audio_out_enabled=True,
            vad_analyzer=SileroVADAnalyzer(),
        ),
    )

    llm = GroqLLMService(
        api_key=os.getenv("GROQ_API_KEY"),
        model="llama-3.3-70b-versatile",
    )

    tts = SonexTTSService(
        api_key=os.getenv("SONEX_API_KEY"),
        voice=os.getenv("SONEX_VOICE_ID"),
        language="en",
        speed=1.0,
        sample_rate=16000,
    )

    pipeline = Pipeline([
        transport.input(),
        stt,
        llm,
        tts,
        transport.output(),
    ])

    runner = PipelineRunner()
    await runner.run(PipelineTask(
        pipeline,
        params=PipelineParams(allow_interruptions=True),
    ))

Telephony (Twilio / Exotel / Vobiz)

Set sample_rate=8000 to match the telephony μ-law transport output rate. Pipecat's SOXR resampler handles 24 kHz → 8 kHz downsampling transparently.

tts = SonexTTSService(
    api_key=os.getenv("SONEX_API_KEY"),
    voice="VOICE_ID",
    language="hi",        # Hindi for India telephony
    sample_rate=8000,
)

Environment variables

SONEX_API_KEY=vsk_your_key_here
SONEX_VOICE_ID=your_voice_id