voiceblender

module
v0.15.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2026 License: MIT

README

VoiceBlender

A Go voice engine that connects SIP, WebRTC, WhatsApp, WebSocket and other call legs into mixable rooms, with recording, speech AI integrations, a REST API and real-time events.

Join our Discord

VoiceBlender architecture

Features

Legs (call endpoints)

  • SIP -- inbound and outbound calls over UDP, TCP and TLS, with digest auth, hold, REFER transfer, early media and session timers
  • SIP trunks & registrations -- register to upstream PBXs/carriers or peer with them by static IP, and act as a registrar for SIP clients
  • Codecs -- PCMU, PCMA, G.722, Opus, AMR-WB, AMR-NB, with mid-call codec renegotiation
  • WebRTC -- browser voice via SDP offer/answer with trickle ICE and ICE restarts
  • WhatsApp Business Calling -- inbound and outbound WhatsApp voice calls
  • WebSocket legs -- raw PCM over WebSocket for bots and custom clients
  • LiveKit -- bridge a LiveKit room, one leg per remote participant
  • MoQ (experimental) -- Media-over-QUIC legs over WebTransport
  • SIPREC -- session recording server and client (RFC 7865 / RFC 7866)
  • Multi-stream SIP calls -- several audio streams in one call, e.g. original and translated audio

Media

  • Rooms -- multi-party mixing (mixed-minus-self) at 8, 16 or 48 kHz
  • Room bridging -- connect two rooms with configurable direction
  • Audio routing matrix -- role-based who-hears-whom for whisper, barge-in and supervisor monitoring
  • Audio filters -- per-leg denoise, band-pass, gain and voice effects (robotic, vocoder, pitch)
  • Comfort noise -- optional per-room background noise
  • DTMF & Real-Time Text -- RFC 4733 telephone-events and T.140 text
  • Recording -- per-leg, per-room or multi-track WAV with pause/resume and S3/GCS upload
  • Playback -- WAV/MP3 files and telephone tones

AI

  • TTS -- ElevenLabs, Google Cloud, AWS Polly, Deepgram, Azure, with speculative preflight synthesis
  • STT -- ElevenLabs, Deepgram, Deepgram Flux, Azure, Speechmatics, with turn detection
  • AI agents -- ElevenLabs, VAPI, Pipecat, Deepgram, attachable to a leg or a whole room
  • Answering machine detection -- human / machine classification with beep detection

Control & observability

  • REST API -- full call and room control (OpenAPI spec)
  • Webhooks -- signed, retried, deduplicated event delivery
  • VSI -- a single WebSocket for events and commands (AsyncAPI spec)
  • Prometheus metrics -- at GET /metrics, plus optional pprof

Quick Start

# Build and run
go build -o voiceblender ./cmd/voiceblender
./voiceblender

# Or run directly
go run ./cmd/voiceblender

The REST API listens on :8080 and SIP on 127.0.0.1:5060 by default. All configuration is via environment variables -- see CONFIGURATION.md and the ready-to-edit voiceblender.env.example.

To try calls between two instances, bring up the two-node cluster:

docker compose -f docker/docker-compose.cluster.yml up --build

API Overview

All endpoints live under /v1. The table is a map only -- see API.md for requests, responses and events.

Area Endpoints
Legs POST /legs (originate sip / whatsapp / websocket / livekit_room), GET /legs, GET|DELETE /legs/{id}
Call control /legs/{id}/ answer, ring, early-media, challenge, mute, deaf, hold, transfer/*, dtmf, rtt
Leg media /legs/{id}/ play, tts, record, stt, agent/*, amd, filters, streams/*, siprec
Inbound legs GET /legs/websocket (WebSocket), CONNECT /legs/moq (WebTransport), POST /webrtc/offer
Rooms POST|GET /rooms, GET|DELETE /rooms/{id}, /rooms/{id}/legs, /rooms/{id}/ws
Room media /rooms/{id}/ play, tts, record, stt, agent/*, siprec
Room topology /rooms/{id}/bridges, /rooms/{id}/routing, PATCH /legs/{id}/role
SIP /sip/registrations, /sip/registrations/attempts/{id}/*, /sip/trunks
Events GET /vsi (WebSocket), webhooks configured globally or per leg / room

Security: the HTTP API has no built-in authentication. Access is gated only by the ALLOWED_IPS allowlist and network placement -- put an authenticating reverse proxy in front of it before exposing it to untrusted networks.

Use Cases

  • Voice AI agents -- put an AI agent on inbound or outbound phone, WhatsApp or browser calls
  • Contact center -- conferencing, transfers, supervisor whisper / barge-in, recording with PCI pause
  • Outbound dialing -- answering machine detection, TTS announcements, DTMF menus
  • Call recording & analytics -- SIPREC recording server with live transcription
  • Live translation -- separate rooms for the original and translated audio of one call
  • Protocol gateway -- bridge SIP, WebRTC, WhatsApp, LiveKit and WebSocket participants in one room

Your First Call

With VoiceBlender running and a SIP endpoint to call, dial it into a room, speak to it, record it and hang up:

API=http://localhost:8080/v1
JSON='Content-Type: application/json'

# Create a room and start recording it
curl -X POST $API/rooms -H "$JSON" -d '{"id":"demo"}'
curl -X POST $API/rooms/demo/record -H "$JSON" -d '{}'

# Dial a SIP phone; it joins the room once answered
LEG=$(curl -s -X POST $API/legs -H "$JSON" \
  -d '{"type":"sip","to":"sip:alice@192.168.1.100:5060","room_id":"demo"}' | jq -r .id)

# After it answers, say something (needs ELEVENLABS_API_KEY), then hang up
curl -X POST $API/legs/$LEG/tts -H "$JSON" \
  -d '{"text":"Hello from VoiceBlender","voice":"Rachel","provider":"elevenlabs"}'
curl -X DELETE $API/legs/$LEG

Watch the call progress (leg.ringing, leg.connected, tts.finished, leg.disconnected, ...) by setting WEBHOOK_URL or connecting a WebSocket client to ws://localhost:8080/v1/vsi.

Noise Suppression

Every leg can run built-in noise suppression (denoise), so a caller in a car, a café or on a noisy trunk reaches everyone else, the recording, STT and the AI agent already cleaned up.

  • Two models, pure Go -- RNNoise via rnnoise-go, or GTCRN (denoise_gtcrn, lower CPU) via gtcrn-go; no cgo, no external service, no per-minute cost
  • Native rate -- denoise runs at the call's own 8, 16 or 48 kHz, with no extra resampling
  • Per leg or server-wide -- set filters on a leg, or AUDIO_FILTERS=denoise as the default
  • Live toggle -- switch it on or off mid-call; suppression ramps in over about a second

Denoise can be chained with bandpass, gain and voice effects -- see Audio filters.

Typical Workflow

1. Configure a webhook        WEBHOOK_URL env var, or per leg / room
2. Receive inbound call       --> webhook: leg.ringing {leg_id, from, to}
3. Answer                     POST /v1/legs/{id}/answer
4. Create a room              POST /v1/rooms
5. Add legs to room           POST /v1/rooms/{id}/legs
6. Attach AI agent            POST /v1/legs/{id}/agent/{provider}
7. Start recording            POST /v1/rooms/{id}/record
8. Hang up                    DELETE /v1/legs/{id}

Documentation

Examples

Complete reference applications built on VoiceBlender live in VoiceBlender/example-applications:

Application Description
contact-centre Inbound contact centre with queues, agent and supervisor dashboards, whisper and monitor
ivr Multi-department DTMF IVR with hold music and an AI voice agent fallback
pbx Multi-tenant SIP PBX with trunks, dial-plan editor and browser softphones
ptt Browser push-to-talk walkie-talkie over WebRTC
interpreter Live two-way speech translation with captions

Testing

go test ./internal/...                                              # unit tests
go test -tags integration -v -timeout 60s ./tests/integration/      # integration tests

See TESTING.md for setup and benchmarks.

Contributing

CLAUDE.md is the checklist for every change -- formatting, spec regeneration, docs and tests. It applies to human contributors and any coding agent alike, not just Claude. CI runs:

gofmt -l .
go vet ./...
go test ./internal/... -count=1 -timeout=60s

AI-Assisted Development

This project was developed with the assistance of Claude Code, Anthropic's AI coding assistant.

License

See LICENSE file.

Directories

Path Synopsis
cmd
asyncapi-gen command
Command asyncapi-gen generates asyncapi.yaml from the VSI command and event registries in internal/api.
Command asyncapi-gen generates asyncapi.yaml from the VSI command and event registries in internal/api.
gen-greetings command
Command gen-greetings uses the ElevenLabs TTS API to generate short human greeting WAV files for AMD false-positive testing.
Command gen-greetings uses the ElevenLabs TTS API to generate short human greeting WAV files for AMD false-positive testing.
gen-noisy-greetings command
Command gen-noisy-greetings builds AMD test fixtures by mixing the clean human greetings with real background noise, so answering-machine detection can be measured on the kind of audio a noisy trunk actually delivers.
Command gen-noisy-greetings builds AMD test fixtures by mixing the clean human greetings with real background noise, so answering-machine detection can be measured on the kind of audio a noisy trunk actually delivers.
openapi-gen command
Command openapi-gen generates openapi.yaml from Go source types and route metadata.
Command openapi-gen generates openapi.yaml from Go source types and route metadata.
voiceblender command
wavdump command
wavdump downloads a WAV file and decodes it using the same pipeline as VoiceBlender's playback, writing the raw PCM output to a file.
wavdump downloads a WAV file and decodes it using the same pipeline as VoiceBlender's playback, writing the raw PCM output to a file.
internal
amd
Package amd implements classic Answering Machine Detection (AMD) by analysing the first few seconds of audio on an outbound call.
Package amd implements classic Answering Machine Detection (AMD) by analysing the first few seconds of audio on an outbound call.
api
audiofilter
Package audiofilter provides an ordered chain of per-leg audio processing stages.
Package audiofilter provides an ordered chain of per-leg audio processing stages.
audiofilter/denoise
Package denoise provides the "denoise" audio filter: RNNoise noise suppression, as a pure-Go port of upstream's current model (github.com/VoiceBlender/rnnoise-go).
Package denoise provides the "denoise" audio filter: RNNoise noise suppression, as a pure-Go port of upstream's current model (github.com/VoiceBlender/rnnoise-go).
audiofilter/denoisegtcrn
Package denoisegtcrn provides the "denoise_gtcrn" audio filter: GTCRN noise suppression via the pure-Go github.com/VoiceBlender/gtcrn-go, an alternative to the RNNoise-backed "denoise" filter.
Package denoisegtcrn provides the "denoise_gtcrn" audio filter: GTCRN noise suppression via the pure-Go github.com/VoiceBlender/gtcrn-go, an alternative to the RNNoise-backed "denoise" filter.
bridge
Package bridge provides an in-memory duplex audio conduit used to join two room mixers together.
Package bridge provides an in-memory duplex audio conduit used to join two room mixers together.
codec/t140
Package t140 implements ITU-T T.140 real-time text packetization with the RFC 4103 RTP payload format and optional RFC 2198 redundancy (text/red).
Package t140 implements ITU-T T.140 real-time text packetization with the RFC 4103 RTP payload format and optional RFC 2198 redundancy (text/red).
jitter
Package jitter implements a fixed-delay RTP jitter buffer (non-adaptive by design).
Package jitter implements a fixed-delay RTP jitter buffer (non-adaptive by design).
leg
lkmedia
Package lkmedia implements the LiveKit signaling protocol and media transport for VoiceBlender's livekit_room leg type.
Package lkmedia implements the LiveKit signaling protocol and media transport for VoiceBlender's livekit_room leg type.
moqmedia
Package moqmedia provides a WebTransport+MoQ transport that carries bidirectional Opus audio for a single VoiceBlender leg.
Package moqmedia provides a WebTransport+MoQ transport that carries bidirectional Opus audio for a single VoiceBlender leg.
resampler
Package resampler implements audio resampler.
Package resampler implements audio resampler.
sip
siprec
Package siprec implements the SIPREC recording metadata model of RFC 7865: the XML document that binds each recorded media stream to the participant whose audio it carries.
Package siprec implements the SIPREC recording metadata model of RFC 7865: the XML document that binds each recorded media stream to the participant whose audio it carries.
stt
tts
wsmedia
Package wsmedia provides a reusable WebSocket transport for bidirectional PCM audio plus text and control messages.
Package wsmedia provides a reusable WebSocket transport for bidirectional PCM audio plus text and control messages.
wsutilx
Package wsutilx provides shared helpers for both halves of a WebSocket client: recv loops and the write path.
Package wsutilx provides shared helpers for both halves of a WebSocket client: recv loops and the write path.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL