i need help with telephony using SIP, in recording...
# ask-ai
e
i need help with telephony using SIP, in recording i can see my voice is too slow and hard to hear, i tried same call with other number and then it is clear. i have used following for room_input_option room_options=room_io.RoomOptions( audio_input=room_io.AudioInputOptions( noise_cancellation=lambda params: noise_cancellation.BVCTelephony() if ( params.participant.kind == rtc.ParticipantKind.PARTICIPANT_KIND_SIP or merged_data.get("kind") == "phone_call" ) else noise_cancellation.BVC(), ), text_input=room_io.TextInputOptions( text_input_cb=make_text_input_cb(agent) ), ),
t
Thanks for reaching out, Aman. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I see you’re troubleshooting SIP telephony recordings where your voice sounds slow and hard to hear (but the same call to another number is clear). You shared your
room_input_option
code and that you use
BVCTelephony()
for SIP participants. Let’s isolate likely causes and walk through targeted checks you can run. Key suspects • Codec / sample-rate mismatch (SIP often uses 8 kHz codecs like G.711; WebRTC/agent code may assume 16/48 kHz). • Over‑aggressive or double noise-cancellation/transcoding in the recording chain. • Incorrect participant-kind detection causing the wrong processing model to be applied. • Additional processing/resampling during egress/recording. Steps to troubleshoot (run these in order) 1. Temporarily disable noise cancellation • Change your
AudioInputOptions
to use
noise_cancellation=None
and make a test call/recording. • If the recording becomes clear, noise cancellation is likely over‑processing telephony audio. 1. Verify sample rate and codec for SIP participants • Confirm the SIP leg uses 8 kHz (narrowband) codecs (e.g., G.711). Ensure your recording/playback path is not resampling 8 kHz audio to 16/48 kHz without proper conversion — that can create slow or low-pitch playback. • If your agent or downstream pipeline expects 8 kHz for SIP, ensure you keep that sample rate for processing and recording for SIP participants. 1. Ensure the right noise model is actually applied • Add logging in the lambda so you can confirm which model is selected for each participant:
Copy code
def noise_filter(params):
      kind = params.participant.kind
      print(f"Participant kind: {kind}")
      if kind == rtc.ParticipantKind.PARTICIPANT_KIND_SIP or merged_data.get("kind") == "phone_call":
          print("Using BVCTelephony()")
          return noise_cancellation.BVCTelephony()
      print("Using BVC()")
      return noise_cancellation.BVC()
• This confirms whether
BVCTelephony()
is applied when you expect it. 1. Check for double processing in the audio chain • Make sure no other component (egress/recorder/telephony gateway) applies additional noise suppression, gain control, or resampling after your agent’s processing. • Test with a minimal pipeline that preserves the inbound codec to see if the issue persists. 1. Compare with the known-good endpoint • Since the same call to another number is clear, test both endpoints while: ◦ Logging codec and sample rate used on each SIP leg. ◦ Recording raw inbound RTP (if possible) to confirm whether distortion is present before agent processing or only after. 1. Egress/recording settings • Ensure your recording/egress settings preserve original encoding or correctly convert sample rates. Unintended resampling at egress can slow/pitch-shift audio. What to try next (recommended sequence) 1. Disable noise cancellation and make a test recording. 2. If problem disappears, re-enable only
BVCTelephony()
for SIP and retest (no other noise filters). 3. If problem remains, capture a short sample of the affected recording and a sample of the raw inbound SIP RTP (or log codec/sample rate) so we can see whether distortion happens pre- or post-agent processing. 4. Share logs that show participant kind detection and the audio pipeline chosen for the affected call. If you’d like, tell me: • The participant kind you see in logs for the problematic calls (what your print/log shows). • The SIP codec and sample rate negotiated for that call (e.g., G.711 @ 8kHz, Opus @ 48kHz). • Whether disabling noise cancellation changed the symptom. With those details I can help pinpoint whether it’s a sample-rate mismatch, noise model over-processing, or an egress/resampling issue and provide exact config/code changes. Sources: Choosing the right noise cancellation for your agent | LiveKit | Troubleshooting STT not picking up utterances | LiveKit | Why is there extra audio at the end of my recordings of an agent session? |... | Python SDKs | livekit/livekit_composite | DeepWiki | Building the all-in-one platform for voice AI agents
e
i'm using Twilio SIP and have added to your livekit cloud, should't it pick the best codec and hz by itself
t
Thanks — you’re asking whether LiveKit Cloud + Twilio SIP will automatically pick the “best” codec and sample rate so you don’t have to worry about the slow/low audio. Short answer: it won’t magically fix every mismatch for you, so you still need to confirm codec/sample-rate negotiation and processing choices for the SIP leg. What actually happens • SIP endpoints and trunks (like Twilio) negotiate codecs and sample rates during call setup. LiveKit Cloud will handle the RTP and media bridging, but it can only use whatever codec/sample rate the SIP side and the WebRTC side negotiate. • If the SIP leg negotiates a narrowband codec (typical telephony codecs are 8 kHz, e.g., G.711), and your agent or downstream pipeline expects wideband (16/48 kHz), playback can sound slow or distorted if audio is resampled incorrectly or processed with the wrong assumptions. • LiveKit’s noise models (for example
BVCTelephony()
vs
BVC()
) are designed for different kinds of audio; picking the wrong processing for a telephony call can degrade clarity. What you should verify and adjust 1. Confirm the codec and sample rate negotiated by Twilio for the problematic calls (e.g., G.711 @ 8 kHz vs Opus @ 48 kHz). 2. Ensure your LiveKit agent and recording/egress path preserve or correctly convert that sample rate: ◦ For SIP (narrowband) prefer processing and recording at 8 kHz, or apply a proper resampler if converting to 16/48 kHz. 1. Make sure the telephony-optimized noise model is actually applied for SIP callers: ◦ Log the participant kind and which noise model your lambda returns so you know
BVCTelephony()
is used for SIP. 1. Disable other noise suppression or duplicate processing layers while testing (to rule out over‑processing). 2. Check egress/recorder settings so they don’t introduce resampling or additional processing that changes pitch/speed. Next steps I can help with • If you share the negotiated codec and sample rate from Twilio for a problematic call, I’ll recommend exact settings to preserve audio or resample correctly. • If you can paste the logs that show participant kind and the noise model selection, I’ll confirm whether your lambda is applying
BVCTelephony()
as intended. • I can provide a minimal AudioInputOptions example to test (no noise cancellation, and explicit handling for SIP) if you want to try that quickly. Tell me which of those you can provide (Twilio codec/sample-rate, participant-kind logs, or a recording sample), and I’ll guide you step‑by‑step.
e
first let me know how to identify participant kind is sip
t
Good question — confirming a participant is SIP is the right first step so you apply
BVCTelephony()
only when appropriate. Below are simple, reliable ways to detect SIP participants and a short code example you can drop into your lambda to log and act on the participant kind. How to identify a SIP participant • Use the participant’s
kind
property and compare it to
rtc.ParticipantKind.PARTICIPANT_KIND_SIP
. • If you also attach metadata when creating participants (e.g.,
merged_data["kind"] = "phone_call"
), check that too as a fallback. • Add logging where you choose the noise model so you can confirm which branch runs for each participant. Example: logging inside your noise-cancellation lambda
Copy code
def noise_filter(params):
    kind = params.participant.kind
    meta_kind = merged_data.get("kind")  # if you use merged metadata
    print(f"Participant id={params.participant.sid} kind={kind} meta_kind={meta_kind}")

    if kind == rtc.ParticipantKind.PARTICIPANT_KIND_SIP or meta_kind == "phone_call":
        print("Detected SIP participant — using BVCTelephony()")
        return noise_cancellation.BVCTelephony()
    print("Non-SIP participant — using BVC()")
    return noise_cancellation.BVC()
What to check in logs • Confirm the printed
kind
equals
PARTICIPANT_KIND_SIP
for the calls you expect to be telephony. • If
kind
is not SIP but you still expect a phone call, check that your system attaches
merged_data["kind"] = "phone_call"
when creating that participant. If the participant kind isn’t SIP when you expect it to be • Share how the SIP participant is created (any metadata you pass) and the logs you see — I can help adjust where to set
merged_data
or how to detect SIP reliably. • If you want, I can provide a minimal test that creates a SIP participant and demonstrates the expected
kind
value.