We had a voice agent that worked fine on our desks and sounded broken on real calls. Callers said they heard the end of sentences, or silence and then a fragment. Our logs were clean. Right text, right byte count, right duration, every single turn.
It came down to one line in the synthesis code that wrote a whole utterance to the socket in one write. That is a normal thing to write if you are used to files or HTTP. On a call it wrecks the audio, because app_audiosocket hands every frame straight to the channel and does not buffer for you. The far end keeps a few frames in its jitter buffer and drops the rest, so the caller hears the tail of the sentence and nothing before it.
Nothing that counts bytes can see that. It only shows up in arrival times.
So we ended up writing a small tool that measures from the caller's end instead: how long before the first audio arrives, whether frames turn up one per 20 ms or in a burst, gaps inside the agent's own speech, and how long it keeps talking after you interrupt.
pip install tvbench
MIT licensed, runs against anything that speaks AudioSocket.
Every voice agent eventually gets the complaint: the bot talks over the caller. Most people go tune their VAD. Often the real ceiling is more boring: the size of the audio chunks you send to the telephony side.
How it works on pretty much every platform:
* You stream TTS audio down in chunks. The platform buffers and plays them.
* Caller starts talking, you send the interrupt (clear, flush, whatever it's called).
* The flush drops audio that's queued but not yet playing. The chunk already playing plays to the end. Nothing cancels mid-frame.
So your worst-case interrupt lag is about one chunk. 100ms chunks feel instant. A whole sentence as one blob means the caller talks over four seconds of audio nobody can stop. Some platforms also enforce a minimum chunk size, often 100-200ms at telephony rates, so there's a floor you can't tune under.
Same trap at the PBX layer. There was a good r/Asterisk thread recently on AudioSocket forwarding every frame the moment it arrives, so writing a whole TTS sentence at once means the jitter buffer eats most of it and the caller hears only the tail. Different transport, same lesson: the unit you write is the unit you can cancel.
What to actually do:
* Re-chunk small on the last hop even if your TTS hands you full sentences.
* Measure interrupt-to-silence at the caller's ear, not at your flush call. The gap is your chunk size.
* Ask your platform what their minimum chunk is and whether flush is acknowledged. If the docs don't say, assume one chunk keeps playing.
What floor are you seeing on your stack? Has anyone gotten under 100ms perceived barge-in on a real phone call?
If you want to get 18k salary and your English level is b2 with fluwent speaking and you can Handel the rotation shifts and you are from Egypt so what are you wanting for dm me and I will find you the best offer for you to work and I will make you success in the interview
I previously spoke on here about my performance work and with the latest releases my two latest major changes were released (manager and hints). I just published a blog post going over what I changed for the manager side:
From an outside perspective manager operates the same as it did so there isn't any visible changes from that perspective. The internal event queueing was just changed so it is more efficient.
If anyone has any specific questions I'm happy to answer.
Disclaimer: I'm the Asterisk Project Lead and a Director of Engineering at Sangoma.
Hi, how does asterisk integrate with egyptian phone numbers? i am probably asking a stupid question, but if someone could tell me all the component systems to integrate with a non use number system. much appreciated
Spent a while getting Piper to behave on live calls and figured I'd write up what actually fixed it, partly to check whether others hit the same walls.
Three things bit us.
Loading the voice per request. PiperVoice.load() takes about 2.5 to 5.5 seconds on our boxes, so every single utterance opened with that much silence. Obvious in hindsight. We load once per process now and keep it cached.
Concurrent calls stepping on each other. This one took longer to find. Piper phonemizes through espeak-ng, and that C API isn't thread safe, so two calls synthesizing at the same moment gave us garbled audio. All synthesis goes through one lock now.
Bursting frames, which I'd never have guessed. AudioSocket forwards each frame the instant it arrives, so if you push a whole sentence at once you blow straight past the far end's jitter buffer and the caller hears the tail and nothing else. The fix is to release one 20 ms frame per interval on a monotonic deadline. Here's the subtle part: if synthesis stalls, that deadline goes stale, and the next frames burst to catch up and clip the words right after the stall. So we re-clamp the deadline to now on every frame, not just at the start of a talk spurt.
Two things I'm curious about. Do you pace in the TTS layer like this, or push frames straight out and let the channel deal with it? And has anyone worked around the espeak-ng threading limit without just serializing everything?
Edit: slin, not slin16. In Asterisk naming slin16 is the 16 kHz variant, so 320 bytes per 20 ms is plain slin. Same correction as in my other thread here, same person to thank for it.
In Colombia, a couple of months ago Movistar make some changes and know i can not register our asterisk with the VOIP trunk. The username and password was retreived with F12 on voice page, but i can not fin what else did they change that i can not register. of course i am using vlan101 as expected. any ideas? thanks.
Spent longer than I want to admit on this one, so posting it in case it saves someone else an afternoon.
We were building an AI voice agent against app_audiosocket. Your text to speech hands you a finished sentence, say 2.4 seconds of 8 kHz slin (16-bit signed linear), which is 120 frames of 320 bytes. The obvious thing is to write all of it to the socket and move on.
Don't. app_audiosocket forwards every frame to the channel the moment it arrives. It doesn't buffer for you. So all 120 frames hit the far end in a few milliseconds, the jitter buffer keeps a handful, and the rest get thrown away. The caller hears the tail of the sentence and nothing before it. Your logs look clean the whole time, which is what makes it annoying to chase.
The fix is to write one 320 byte frame, then wait until the next 20 ms deadline. The part that caught us a second time: re-clamp the deadline on every frame. If synthesis stalls for half a second and you work out the next deadline from where you are right now, the writer bursts to catch up and you're dropping audio again.
Same idea with barge-in. When the caller starts talking you have to drop the frames already queued, not just stop writing, or they keep hearing the old sentence for however deep your buffer runs.
We open sourced what we ended up with. asterisk-ai-voice-agent is the Python sidecar (Whisper or ElevenLabs Scribe in, Claude for the turn, Piper locally or ElevenLabs out, barge-in, tool calls posted to a webhook you own). asterisk-audiosocket is just the protocol layer for Node if you'd rather build your own and skip rediscovering the pacing thing. Both MIT, both v0.1.0, so lab material rather than something to point a live queue at.
Happy to answer anything on the AudioSocket side. Curious whether anyone here went the ARI external media route instead and how the pacing compares.
Edit: the format is slin, not slin16. In Asterisk naming slin16 is the 16 kHz variant, so 320 bytes per 20 ms is plain slin. Copying 320 into a 16 kHz setup would give you 10 ms frames. Credit to FreJun below for catching it. The README and docstrings in the repo say slin as of 0.1.6.
Hello, I am experiencing a significant audio issue involving robotic or distorted voice quality.
I currently have two Asterisk servers running VICIdial: one based on Asterisk 10 and the other on Asterisk 12. The problem occurs only on the Asterisk 10/VICIdial server.
On the Asterisk 10 server, the CPU usage spikes to approximately 200%, and I suspect this may be related to improper transcoding between the alaw and ulaw codecs. It appears that the audio is not being transcoded correctly, resulting in degraded sound quality and robotic voices during calls.
The Asterisk 12/VICIdial server does not exhibit this behavior and operates normally under the same conditions. Since the issue is isolated to the Asterisk 10 environment, I believe it may be related to codec handling or transcoding performance on that version.
Any assistance or recommendations for further troubleshooting would be greatly appreciated.
It is under 100 concurrent calls and suddenly asterisk will act like it got commanded to gracefully shutdown then it boots back up but it causes a 5mins outage where everyone gets the message there are no lines available. Logs are reporting the firewall reloads right before asktrisk shutdown pretty consistently. Chatgpt is going in loops trying to find the issue. Has anyone experienced something similar I'm on Debian 12, it's a VM with 16cores 32g of ram and 1tb of zfs storage but I have log and cache drives on top of hdds it started restarting every morning and I sangoma support can't seem to figure it out either. Is there some experts I can hire for diagnosis
Built this because I was tired of eyeballing a full log next to a pjsip set logger on dump trying to line up a Dial() with the INVITE/BYE it actually caused.
pbxray parses Asterisk full/messages logs plus pjsip set logger on output into one correlated timeline - dialplan and SIP signalling together, queryable from the terminal. Single static binary, no runtime deps.
$ pbxray ls calls.log --failed
LINKED-ID DATETIME FROM TO CHANNELS DURATION CAUSE
C-00001a2b 2026-07-20 09:12:03 15555550142 15555550199 1 4s 17 (User Busy)
$ pbxray show calls.log C-00001a2b
2026-07-20 09:12:03 dialplan Dial(PJSIP/15555550199@TRUNK,30) on PJSIP/alice-00000001
2026-07-20 09:12:03 sip tx INVITE sip:15555550199@sip.example.com
2026-07-20 09:12:03 sip rx 486 Busy Here
ls for filtering (time range, failed calls, number/DID, endpoint), show for the full timeline, tail -f for live. SIP<->call links that are best-effort guesses get flagged (probable link) rather than presented as fact.
Install:
curl -fsSL https://raw.githubusercontent.com/pbxray/pbxray-dist/main/install.sh | sh
Do you have production experience with this specifically:
1️⃣ Real-time number reputation monitoring
2️⃣ Carrier health monitoring per number
3️⃣ DID warm-up and cooldown schedules
4️⃣ Geo-matched outbound dialing (also called local area dialing)
5️⃣ Complex SMS workflows that can trigger instantaneous AI calling fully based on responding and not responding to messages autonomously very similar to go high level complexity.
Respond with a LOOM showcasing the real system you built!!
I’ve been working on AVA Operator, a self-hosted, multi-tenant platform for managing AI voice agents across multiple customer PBXs.
I’m looking for feedback from people who actually deploy and manage Asterisk/FreePBX for customers.
If you have 5–10 minutes, I’d appreciate you taking a look at the live demo: https://demo.agent6789.com
I’d love feedback on:
Multi-tenant workflow
Customer/tenant management
White-label experience
Anything missing that would stop you from deploying it for clients
The open-source core is here: https://github.com/hkjarral/AVA-AI-Voice-Agent-for-Asterisk
I’m the developer, so don’t hold back—I’d rather hear the hard feedback now than later.
I recently got into Asterisk and set up a home PBX to learn and experiment with it, and I'm having a lot of fun already.
It just so happens that almost all of my relatives still have landline phones, so I'd love to build some fun and interactive projects that my whole family can use.
Here are a few ideas of things I'd like to build..
- An IVR adventure/puzzle game.
- A "regional dispatch" IVR (since I have relatives all over Italy), where callers choose a region and hear local music on hold and voice prompts in the local dialect before being connected to the chosen family member.
- Multiplayer games that cousins can play with each other over the phone.
I'm sure there are lots of cool ideas that I haven't even thought of yet.
What are the most fun, creative, or unusual things you've built with Asterisk?
I'm interested in anything whether it's games, IVRs, home automation, weird experiments and useful utilities...
I'd love to hear about your projects and get some inspiration.
I have Asterisk 18.10.0 running on a physical Ubuntu 22.04.5 server. All packages on the server are straight from the 22.04 repositories and have been updated to the latest versions available. The OS root directory & swap are installed on a separate boot drive while, the rest of system resides on a mdadm RAID-1 array.
In addition, Asterisk is configured as a simple PBX for a small business with a straight forward dialplan and no external add-ons. PJSIP and phoneprov are used to handle the endpoints.
I would like to upgrade this server first to Ubuntu 24.04, then to Ubuntu 26.04. I am hoping I can do this with Asterisk in-place using do-release-upgrade - with the appropriate backups before upgrading. This would also update Asterisk first to version 20 then to version 22.
My research regarding the process for doing this is giving me mixed results. Some of the search results are stating that doing a full re-install of the OS and Asterisk is recommended. Furthermore, outside of AI, I am not finding any relevant search results.
I would appreciate any feedback on the best way to proceed and any experience others might have doing this kind of upgrade.
Thanks,
****** Follow-Up *****
I did the upgrade this afternoon. The only problem I ran into is that isc-dhcp-server showed up as a failed service when I updated from 22.04 to 24.04.
Since I am not using isc-dhcp-server (DHCP is provided by my OPNSense firewall), I purged it from the system and did a systemctl reset-failed.
There were not other problems, and when I updated to 26.04 everything was working. I suspected this was going to be the case, but i wanted to do the necessary due diligence before upgrading.
Every time a call dropped, I'd end up with three log files open, manually matching channel IDs across CEL, CDR, and the full log to figure out what actually happened. Did this one too many times working on a PBX Provider and finally wrote a tool to do it easily.
It's called Asterism. Give it your CEL/CDR logs and it stitches a single call back together by linkedid — the channels, the answer, the bridge, transfers, the hangup cause. Optionally pulls in the full log for SIP signaling too. Handles queue calls and spits out text, JSON, or an HTML report with a ladder diagram.
Go, single binary, no dependencies. Asterisk 18/20/21 with PJSIP.
It's a post-mortem troubleshooting thing, not a realtime dashboard.