Master codec selection and negotiation strategies for ViciDial deployments to optimize call quality, bandwidth, and server performance across different carrier and endpoint configurations.
Prerequisites
Before following this tutorial, ensure you have:
- A working Asterisk/ViciDial installation (v2.14+ recommended)
- Root or sudo access to the Asterisk server
- Basic familiarity with Asterisk configuration files (
sip.conf,extensions.conf) - Understanding of SIP protocol basics
- Access to your carrier's supported codec list
- A test extension or softphone configured for testing
tcpdumporngrepinstalled for packet analysis- Familiarity with
asterisk -rxCLI commands
Understanding Codec Negotiation Fundamentals
What is Codec Negotiation?
Codec negotiation is the process by which two SIP endpoints determine which audio compression algorithm they will use for a call. When a call is initiated, the caller sends an SDP (Session Description Protocol) offer listing all codecs it supports, ordered by preference. The callee responds with an SDP answer, selecting the first codec from the offer that it also supports.
In ViciDial environments, this negotiation happens at three critical points:
- Agent to Asterisk (softphone or hardphone)
- Asterisk to Carrier (outbound SIP trunk)
- Carrier to Remote Party (destination network)
Misaligned codec preferences cause unnecessary transcoding—consuming CPU and degrading quality. Understanding and controlling this negotiation is essential for production deployments.
Why Codec Selection Matters in ViciDial
ViciDial call centers operate under strict constraints:
- Bandwidth: Multiple concurrent calls on limited uplinks
- CPU: Transcoding 50+ simultaneous calls drains processor resources
- Quality: Agents must hear clearly; compressed audio creates fatigue
- Carrier Costs: Bandwidth charges directly impact margins
- Latency: Compression adds processing delay
Choosing G.711 everywhere means crystal-clear calls but 64 kbps per leg. Choosing G.729 everywhere saves bandwidth but requires licensing. Opus offers the best compression with modern quality but requires modern endpoints.
The Three Primary Codecs Explained
G.711 (μ-Law and A-Law)
Technical specs:
- Bitrate: 64 kbps
- Sampling: 8 kHz
- Delay: <1 ms
- Complexity: Very low (no processing)
- Standard: PSTN standard
Advantages:
- No transcoding loss (direct PSTN bridge possible)
- Zero processing overhead
- Universal support
- Best quality for speech
Disadvantages:
- High bandwidth consumption
- No compression whatsoever
- Not suitable for bandwidth-limited scenarios
ViciDial use case: Local carrier trunks, LAN-based agents, high-bandwidth WAN links, premium customer accounts.
G.729
Technical specs:
- Bitrate: 8 kbps (or 16 kbps with DTX)
- Sampling: 8 kHz
- Delay: 10-15 ms
- Complexity: Medium-high
- Licensing: Required (per-channel)
Advantages:
- Excellent compression (8:1 ratio)
- Maintains acceptable speech quality
- Lower bandwidth than G.711
- Works across most carriers
Disadvantages:
- Requires commercial licensing ($10-25 per concurrent channel)
- Noticeable delay compared to G.711
- Requires CPU for transcoding
- Quality degradation in noisy environments
ViciDial use case: Remote agents over internet, international calls, bandwidth-constrained carriers, cost-sensitive operations.
Opus
Technical specs:
- Bitrate: 6-128 kbps (variable)
- Sampling: 8-48 kHz
- Delay: 5-20 ms
- Complexity: Medium
- Licensing: Free (RFC 6716)
Advantages:
- Superior compression with high quality
- Adaptive bitrate (scales to network conditions)
- Free and open-source
- Excellent for varying bandwidth scenarios
- Better quality than G.729 at same bitrate
Disadvantages:
- Limited carrier support (primarily cloud/VoIP providers)
- Requires modern endpoints
- Not PSTN-compatible
- Less mature than G.711/G.729
ViciDial use case: Cloud-based carrier connections (VoIP.ms, Twilio, Bandcamp), modern SIP endpoints, internal trunk connections, WebRTC integration.
Configuring Codec Preferences in Asterisk
Step 1: Understanding Asterisk Codec Configuration
Asterisk defines codecs in several places with a hierarchy:
Global preference (sip.conf)
↓
Peer/User level (sip-vicidial.conf)
↓
Outbound proxy/carrier level
↓
Actual negotiation (what both sides support)
Step 2: Edit Global SIP Configuration
Navigate to /etc/asterisk/sip.conf and locate the [general] section:
[general]
context=default
allowguest=no
nat=force_rport,comedia
srvlookup=yes
udpbindaddr=0.0.0.0
; Codec configuration - order matters (top = preferred)
disallow=all
allow=g711u
allow=g711a
allow=g729
allow=opus
; Quality-of-service settings
tos_sip=cs3
tos_audio=ef
cos_sip=3
cos_audio=5
; Performance tuning
maxcallbitrate=384
videosupport=no
The disallow=all followed by specific allow statements creates an explicit whitelist. The order in allow statements determines preference order.
Step 3: Configure ViciDial-Specific SIP Peers
Edit /etc/asterisk/sip-vicidial.conf. This file is generated by ViciDial's admin interface but can be manually tweaked.
For internal agent extensions:
[6000]
type=friend
context=vicidial
host=dynamic
nat=force_rport,comedia
disallow=all
allow=opus
allow=g711u
allow=g711a
allow=g729
secret=PASSWORD123
mailbox=6000@vicidial
port=5060
qualify=yes
qualifyfreq=30
defaultuser=6000
For carrier trunks (outbound):
[carrier-outbound]
type=peer
host=sip.carrier.com
port=5060
context=from-carriers
nat=no
insecure=port,invite
disallow=all
allow=g711u
allow=g729
secret=CARRIER_SECRET
fromuser=YOUR_DID
fromdomain=sip.carrier.com
canreinvite=no
directmedia=no
rtptimeout=60
rtpholdtimeout=300
For internal Asterisk-to-Asterisk trunks:
[internal-remote-pbx]
type=friend
host=10.20.30.40
port=5060
context=from-internal-trunks
nat=no
disallow=all
allow=opus
allow=g711u
canreinvite=yes
directmedia=yes
Step 4: Create Codec-Specific Carrier Configurations
In production, you'll often have multiple carriers with different codec support. Create separate peer definitions:
; Carrier A: Supports G.711 and G.729
[carrier-a-main]
type=peer
host=sip1.carriera.com
disallow=all
allow=g711u
allow=g729
secret=CARRIER_A_SECRET
fromuser=ACCOUNT_ID_A
; Carrier B: Opus-native carrier (lower cost)
[carrier-b-premium]
type=peer
host=api.voipprovider.io
disallow=all
allow=opus
allow=g711u
secret=CARRIER_B_SECRET
; Fallback carrier: Only G.711 (legacy)
[carrier-legacy]
type=peer
host=sip.oldcarrier.com
disallow=all
allow=g711u
secret=LEGACY_SECRET
Step 5: Configure Dialplan for Codec Selection
Edit /etc/asterisk/extensions-vicidial.conf to implement codec routing logic:
[vicidial-inbound]
exten => _X.,1,Verbose(1,Incoming call from ${CALLERID(num)} to ${EXTEN})
same => n,Set(CHANNEL(hangup_handler_push)=vicidial-cleanup,s,1)
same => n,Gosub(vicidial-agent-routing,${EXTEN},1)
[vicidial-outbound-routing]
; Route to carrier based on destination pattern and codec capability
exten => _1NXXNXXXXXX,1,Verbose(2,Outbound: ${EXTEN} via smart routing)
same => n,Set(DEST=${EXTEN})
same => n,GotoIf($["${DEST:0:3}" = "011"]?international:domestic)
exten => international,1,Verbose(2,International call - using G.729)
same => n,Dial(SIP/carrier-b-premium/${DEST},60,tT)
same => n,Hangup()
exten => domestic,1,Verbose(2,Domestic call - using G.711)
same => n,Dial(SIP/carrier-a-main/${DEST},60,tT)
same => n,Hangup()
Practical Configuration Strategies
Strategy 1: High-Quality LAN Deployment
Scenario: Call center with 50 agents on the same network, gigabit backbone, premium carrier.
; /etc/asterisk/sip.conf [general]
disallow=all
allow=g711u
allow=g711a
; /etc/asterisk/sip-vicidial.conf [agent-extensions]
disallow=all
allow=g711u
allow=g711a
; /etc/asterisk/sip-vicidial.conf [carriers]
disallow=all
allow=g711u
allow=g729
Why: G.711 throughout the LAN provides maximum quality and zero transcoding. Carriers offer G.729 as fallback.
Bandwidth consumption: 1 call = 128 kbps (64 kbps each direction + overhead)
Strategy 2: Cloud-Based Remote Agents
Scenario: 100 remote agents on internet connections, cost-sensitive, modern VoIP provider.
; /etc/asterisk/sip.conf [general]
disallow=all
allow=opus
allow=g729
allow=g711u
; /etc/asterisk/sip-vicidial.conf [agent-extensions]
disallow=all
allow=opus
allow=g729
allow=g711u
; /etc/asterisk/sip-vicidial.conf [carriers]
disallow=all
allow=opus
allow=g711u
Why: Opus's variable bitrate adapts to network conditions. Falls back to G.729 for older softphones.
Bandwidth consumption: 1 call = 40-80 kbps average (Opus adapts), or 72 kbps minimum (G.729)
Strategy 3: Multi-Carrier Optimization
Scenario: 30 agents, multiple carriers with different codec support, mixed domestic/international.
Create carrier-specific profiles in a routing context:
[determine-carrier]
exten => _1NXXNXXXXXX,1,Verbose(2,Determining carrier for ${EXTEN})
; Domestic US routing (premium carrier supports all codecs)
same => n,GotoIf($["${EXTEN:0:1}" = "1"]?us-domestic)
; International routing (G.729 only)
same => n,GotoIf($["${EXTEN:0:3}" = "011"]?intl)
exten => us-domestic,1,Set(CARRIER=carrier-primary)
same => n,Set(CODEC_PREF=g711u)
same => n,Return()
exten => intl,1,Set(CARRIER=carrier-intl-gcc)
same => n,Set(CODEC_PREF=g729)
same => n,Return()
Monitoring and Debugging Codec Negotiation
Check Active Codec on Running Call
asterisk -rx "sip show channels"
Output shows connected calls with negotiated codecs:
Peer Call ID Duration Recv: Format Send: Format
AGENT-6001 abc123@pbx 00:01:23 (opus) (opus)
carrier-a xyz789@sip 00:02:45 (g729) (g729)
Detailed SIP Channel Information
asterisk -rx "sip show channel SIP/6001-00000001"
Returns:
Channel: SIP/6001-00000001
From: <sip:[email protected]>
To: <sip:[email protected]>
Codecs: (g711u|g729)
Non-Codec Capabilities: (nothing)
Dtmf Mode: rfc2833
SIP Options: replaces, timer
Status: Up (CallID: abc@pbx, VoiceQuality: 0)
Codec Order (Outbound): g711u(64000), g729(8000)
Codec Order (Inbound): g711u(64000), g729(8000)
Packet-Level Inspection
Use ngrep to see actual SDP offer/answer:
sudo ngrep -W byline 'INVITE|200 OK|SDP' 'host 10.0.0.50 and port 5060'
Look for the m=audio line:
m=audio 15000 RTP/AVP 0 18 97
a=rtpmap:0 PCMU/8000
a=rtpmap:18 G729/8000
a=rtpmap:97 opus/48000
Numbers (0, 18, 97) correspond to codec payload types. First listed is preferred.
ViciDial-Level Logging
Enable verbose logging in Asterisk:
asterisk -rx "sip set debug on"
asterisk -rx "core set verbose 3"
Tail logs:
tail -f /var/log/asterisk/messages | grep -i codec
Check Transcoding Load
Monitor CPU usage during calls with transcoding:
asterisk -rx "core show system uptime"
asterisk -rx "core show threads"
Compare CPU with and without transcoding to quantify impact.
ViciDial Integration Points
Carrier Configuration via Admin Interface
In ViciDial web admin (/vicidial/admin.php):
- Go to Carrier Management → Add/Edit Carriers
- Locate the Preferred Codec dropdown
- Select primary codec (usually
G711Ufor standard,G729for savings)
The admin interface writes to vicidial_carrier_list table:
SELECT carrier_id, carrier_name, allow_codec FROM vicidial_carrier_list;
Example output:
carrier_id | carrier_name | allow_codec
-----------|------------------------|-------------
1 | Primary Carrier | G711U,G729
2 | International Gateway | G729
3 | Premium VoIP Provider | OPUS,G711U
Agent Codec Preferences
Agent-specific preferences are stored in vicidial_users table:
SELECT user_id, full_name, preferred_codec FROM vicidial_users WHERE user_id='6001';
Manually set codec preference (if admin interface doesn't support):
UPDATE vicidial_users SET preferred_codec='G729' WHERE user_id='6001';
Call Quality Tracking
After calls complete, check vicidial_log table for quality indicators:
SELECT
unique_id,
user,
call_date,
call_duration,
codec_used,
mos_score
FROM vicidial_log
WHERE call_date >= DATE_SUB(NOW(), INTERVAL 1 DAY)
ORDER BY call_date DESC
LIMIT 20;
(Note: MOS scoring requires additional quality monitoring modules)
Reload Configuration Without Restart
After modifying codec settings, reload Asterisk without dropping calls:
asterisk -rx "sip reload"
Verify changes applied:
asterisk -rx "sip show peers" | grep -A5 "carrier-a-main"
Troubleshooting Codec Negotiation
Problem 1: One-Way Audio or No Audio
Symptom: Call connects but one or both parties hear nothing.
Root cause: Endpoints support different codecs; Asterisk lacks transcoding permission.
Diagnosis:
asterisk -rx "sip show channel SIP/6001-00000001" | grep Codecs
If output shows Codecs: (nothing) or mismatched codec lists, codec negotiation failed.
Solution:
; Add matching codec to both sides in sip-vicidial.conf
[6001]
allow=g711u
allow=g729
[carrier-x]
allow=g711u
allow=g729
Reload and retry:
asterisk -rx "sip reload"
Problem 2: Excessive CPU Usage During Calls
Symptom: CPU spikes when calls connect; agent reports call quality degradation.
Root cause: Unnecessary transcoding between codecs.
Diagnosis:
asterisk -rx "sip show channels"
If call shows different codecs in "Recv" and "Send" formats (e.g., recv: opus, send: g711u), transcoding is active.
Solution: Align codec preference. If carrier only supports G.729 but agent uses Opus:
[6001]
; Prioritize G.729 to match carrier
disallow=all
allow=g729
allow=g711u
allow=opus
Or upgrade carrier to support Opus.
Problem 3: G.729 License Exhaustion
Symptom: G.729 calls fail midway or fail to connect; other codecs work.
Error in logs:
ERROR: g729 codec license limit exceeded
Diagnosis:
asterisk -rx "codec show"
Look for G.729 license count.
Solution:
Purchase additional licenses or switch to G.711 (uncompressed) or Opus (free).
; Temporary workaround: prioritize G.711
disallow=all
allow=g711u
allow=opus
Problem 4: Carrier Rejecting Codec Offer
Symptom: Calls to specific carrier fail with SIP 488 "Not Acceptable Here"
Diagnosis: Use ngrep to capture SDP offer:
sudo ngrep -W byline 'INVITE' 'host CARRIER_IP and port 5060'
Check what codecs you're offering vs. what carrier accepts.
Solution: Contact carrier for supported codec list and update peer configuration:
[carrier-problematic]
type=peer
host=sip.carrier.com
; Restrict to codecs carrier actually supports
disallow=all
allow=g711u
allow=g729
Problem 5: Codec Misalignment After Config Change
Symptom: Changed codec settings in config file but calls still use old codec.
Root cause: Asterisk daemon hasn't reloaded configuration.
Solution:
# Reload SIP module
asterisk -rx "sip reload"
# If that doesn't work, reload entire Asterisk
asterisk -rx "core reload"
# Verify change with specific peer
asterisk -rx "sip show peer carrier-a-main"
Performance Benchmarking
CPU Impact by Codec
Test transcoding load on your hardware. Create a test call and monitor:
# Terminal 1: Start monitoring
watch -n1 'asterisk -rx "core show threads" | head -20'
# Terminal 2: Run synthetic call load
for i in {1..10}; do
asterisk -rx "channel originate SIP/6001 extension 1000@test-context"
done
Typical results on modern server (Intel Xeon 2.4 GHz):
| Scenario | CPU/call | Calls/core |
|---|---|---|
| G.711 passthrough | 0.5% | 200 |
| G.729 passthrough | 1% | 100 |
| G.711↔G.729 transcode | 3-5% | 20-30 |
| Opus↔G.729 transcode | 4-6% | 15-25 |
Bandwidth Impact
Monitor SIP trunk bandwidth:
# Install iftop
sudo apt-get install iftop
# Monitor specific interface
sudo iftop -i eth0 -nNP
# Or use vnstat for long-term stats
sudo vnstat -h -i eth0
Expected bandwidth per codec:
| Codec | Bitrate | Per call (both directions) |
|---|---|---|
| G.711 | 64 kbps | 128 kbps |
| G.729 | 8 kbps | 16 kbps |
| Opus @ 24kbps | 24 kbps | 48 kbps |
Production Checklist
Before deploying codec changes to production:
- Test codec pair: Verify each inbound/outbound codec combination in lab
- Carrier coordination: Confirm carrier supports all configured codecs
- Backup config: Save current
/etc/asterisk/sip-vicidial.conf - Load test: Run load test with new codec settings for 30+ minutes
- Audio quality check: Have QA test call quality on live codec settings
- Monitor metrics: Check CPU, bandwidth, call quality metrics for 24 hours
- Agent feedback: Collect feedback from agents on audio quality
- Rollback plan: Document how to revert if issues occur
Summary
Codec negotiation in Asterisk/ViciDial is the intersection of quality, bandwidth, and processing power. The optimal choice depends on your specific constraints:
Choose G.711 if:
- Bandwidth is abundant and cheap
- Call quality is paramount
- CPU resources are plentiful
- Agents are on LAN with premium carriers
Choose G.729 if:
- Bandwidth is limited or expensive
- You have G.729 licensing budget
- Remote agents on internet connections
- Legacy carrier support is required
Choose Opus if:
- Using modern VoIP providers (Twilio, VoIP.ms, etc.)
- Variable bandwidth network conditions
- Cost optimization with quality maintained
- Cloud-first infrastructure
In production ViciDial deployments:
- Define your constraint: bandwidth, CPU, or quality
- Map carrier capabilities: Know what each carrier supports
- Configure hierarchical preferences: Global defaults with peer overrides
- Monitor continuously: Track CPU, bandwidth, and MOS scores
- Test thoroughly: Lab validation before production rollout
- Document decisions: Record why each codec choice was made
The most common mistake is forcing a single codec globally when a multi-codec strategy (high-quality internal, optimized external) works better. Use codec negotiation as a tool to balance competing demands, not as a binary choice.