Skip to content
Docs

Transport Providers — Voice I/O

Beluga AI provides a unified transport.AudioTransport interface for bidirectional audio I/O between clients and the voice pipeline. Transport providers abstract the underlying protocol (WebSocket, WebRTC, server-to-server) so that voice processing logic remains transport-agnostic.

All transport providers implement the same interface:

type AudioTransport interface {
Recv(ctx context.Context) (<-chan voice.Frame, error)
Send(ctx context.Context, frame voice.Frame) error
AudioOut() io.Writer
Close() error
}

You can instantiate any provider two ways:

Via the registry (recommended for dynamic configuration):

import (
"github.com/lookatitude/beluga-ai/voice/transport"
_ "github.com/lookatitude/beluga-ai/voice/transport/providers/livekit"
)
t, err := transport.New("livekit", transport.Config{
URL: "wss://myapp.livekit.cloud",
Token: "...",
})

Via direct construction (for compile-time type safety):

import "github.com/lookatitude/beluga-ai/voice/transport/providers/livekit"
t, err := livekit.New(transport.Config{
URL: "wss://myapp.livekit.cloud",
Token: "...",
})

All providers accept transport.Config:

FieldTypeDescription
URLstringTransport endpoint URL
TokenstringAuthentication token
SampleRateintAudio sample rate in Hz (default: 16000)
ChannelsintAudio channels: 1=mono, 2=stereo
Extramap[string]anyProvider-specific configuration

Functional options are also available:

cfg := transport.Config{}
transport.WithURL("wss://...")(&cfg)
transport.WithToken("...")(&cfg)
transport.WithSampleRate(16000)(&cfg)
transport.WithChannels(1)(&cfg)
ProviderRegistry NameProtocolDescription
WebSocketwebsocketWebSocketBuilt-in WebSocket transport
DailydailyWebRTCDaily.co room-based audio transport
LiveKitlivekitWebRTCLiveKit room-based audio transport
PipecatpipecatWebSocketPipecat server audio transport

The transport package includes a built-in WebSocket transport that requires no additional imports:

import "github.com/lookatitude/beluga-ai/voice/transport"
t, err := transport.New("websocket", transport.Config{
URL: "ws://localhost:8080/audio",
SampleRate: 16000,
Channels: 1,
})

Or construct directly with WebSocket-specific options:

t := transport.NewWebSocketTransport("ws://localhost:8080/audio",
transport.WithWSSampleRate(16000),
transport.WithWSChannels(1),
)

LiveKit, Daily, and similar services are treated as transports, not framework dependencies. These services provide the real-time communication layer (WebRTC, WebSocket), while Beluga handles all STT, LLM, and TTS processing through its frame-based pipeline. This separation ensures that switching transports does not require changes to voice processing logic.

Use AsVoiceTransport to adapt an AudioTransport for the voice pipeline:

audioTransport, err := transport.New("livekit", cfg)
if err != nil {
log.Fatal(err)
}
voiceTransport := &transport.AsVoiceTransport{T: audioTransport}
pipe := voice.NewPipeline(
voice.WithTransport(voiceTransport),
voice.WithVAD(vad),
voice.WithSTT(sttEngine),
voice.WithLLM(model),
voice.WithTTS(ttsEngine),
)

List all registered transport providers at runtime:

for _, name := range transport.List() {
fmt.Println(name)
}
Use CaseRecommended ProviderReason
Browser clientslivekit or dailyWebRTC handles NAT traversal and adaptive bitrate
Server-to-serverwebsocketSimple protocol, no WebRTC overhead
Pipecat interoppipecatNative integration with Pipecat pipelines
Low-latency productionlivekitGlobal edge network with SFU routing
Quick prototypingwebsocketBuilt-in, zero external dependencies