Skip to content

Raw Call Audio (Audio Mode)

Voice gateways normally run a conversation pipeline on every call: speech recognition, an LLM, and speech synthesis (text mode), or a voice-to-voice model (realtime mode). The pipeline listens and answers on its own, which suits a one-to-one call with an assistant.

Audio mode runs no pipeline. The gateway still answers webhooks, connects the media stream, and tracks the call, but it hands the call's audio to your application and plays the audio your application sends. Use it when the application decides when to listen and when to speak, for example:

  • an agent attending a meeting by phone, which records and transcribes everyone but speaks only when addressed
  • a call recorder or live transcription service
  • a custom pipeline that does not fit text or realtime mode

Enabling Audio Mode

Set the gateway's pipeline mode to gateway.PipelineModeAudio. With omni-twilio:

import (
    coregateway "github.com/plexusone/omnivoice-core/gateway"
    twiliogateway "github.com/plexusone/omni-twilio/omnivoice/gateway"
)

gw, err := twiliogateway.New(twiliogateway.Config{
    AccountSID:  os.Getenv("TWILIO_ACCOUNT_SID"),
    AuthToken:   os.Getenv("TWILIO_AUTH_TOKEN"),
    PhoneNumber: "+14155550199",
    PublicURL:   "https://your-server.com",
    Mode:        coregateway.PipelineModeAudio,
})

No STT, LLM, or TTS configuration is needed in audio mode.

Using the Session

Sessions of an audio-mode gateway implement gateway.AudioSession:

Method Purpose
AudioFormat() Format of the audio in both directions, for example mu-law 8 kHz mono
ReceiveAudio() Channel of the remote party's audio; closed when the call ends
SendAudio(audio) Play audio into the call
ClearAudio() Discard audio sent but not played yet, for example when interrupted
sess, err := coregateway.MakeCallWithOptions(ctx, gw, "+16695550100",
    callsystem.WithSendDigits("WWWW85012345678#"),
)
if err != nil {
    return err
}
audio, ok := sess.(coregateway.AudioSession)
if !ok {
    return errors.New("gateway is not in audio mode")
}

go func() {
    for chunk := range audio.ReceiveAudio() {
        recorder.Write(chunk) // or send to a streaming STT provider
    }
}()

Audio flows once the media stream connects, which the session reports with an EventSessionStarted event. Before then, SendAudio returns ErrAudioNotConnected; after the call ends it returns ErrSessionClosed. When the media stream stops, the session sends EventSessionEnded, closes the ReceiveAudio channel, and closes itself.

The session type assertion succeeds only in audio mode, so code can check which mode a gateway runs in by asserting AudioSession.

Audio Format

Audio stays in the provider's telephony format. Convert it with the audio/converter package when a speech provider or recorder needs PCM:

Provider Format
omni-twilio mu-law, 8 kHz, mono (format.Twilio)
omni-telnyx mu-law (PCMU), 8 kHz, mono (format.Telnyx)

On a conference line, ReceiveAudio carries one mixed stream of everyone on the call, not a stream per speaker.

Provider Support

Audio mode requires the omni-twilio and omni-telnyx releases built on omnivoice-core v0.18.0. Other gateways do not support it yet.