DEV Community

Moisi Trungu
Moisi Trungu

Posted on • Originally published at flixzone.icu

Asterisk Codec Negotiation — G.711 vs G.729 vs Opus

Asterisk Codec Negotiation — G.711 vs G.729 vs Opus

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
  • tcpdump or ngrep installed for packet analysis
  • Familiarity with asterisk -rx CLI 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:

  1. Agent to Asterisk (softphone or hardphone)
  2. Asterisk to Carrier (outbound SIP trunk)
  3. 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)
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

Monitoring and Debugging Codec Negotiation

Check Active Codec on Running Call

asterisk -rx "sip show channels"
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

Detailed SIP Channel Information

asterisk -rx "sip show channel SIP/6001-00000001"
Enter fullscreen mode Exit fullscreen mode

Returns:

Channel: SIP/6001-00000001
From: <sip:6001@10.0.0.50>
To: <sip:1234567890@sip.carrier.com>
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)
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

Tail logs:

tail -f /var/log/asterisk/messages | grep -i codec
Enter fullscreen mode Exit fullscreen mode

Check Transcoding Load

Monitor CPU usage during calls with transcoding:

asterisk -rx "core show system uptime"
asterisk -rx "core show threads"
Enter fullscreen mode Exit fullscreen mode

Compare CPU with and without transcoding to quantify impact.

ViciDial Integration Points

Carrier Configuration via Admin Interface

In ViciDial web admin (/vicidial/admin.php):

  1. Go to Carrier ManagementAdd/Edit Carriers
  2. Locate the Preferred Codec dropdown
  3. Select primary codec (usually G711U for standard, G729 for savings)

The admin interface writes to vicidial_carrier_list table:

SELECT carrier_id, carrier_name, allow_codec FROM vicidial_carrier_list;
Enter fullscreen mode Exit fullscreen mode

Example output:

carrier_id | carrier_name           | allow_codec
-----------|------------------------|-------------
1          | Primary Carrier        | G711U,G729
2          | International Gateway  | G729
3          | Premium VoIP Provider  | OPUS,G711U
Enter fullscreen mode Exit fullscreen mode

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';
Enter fullscreen mode Exit fullscreen mode

Manually set codec preference (if admin interface doesn't support):

UPDATE vicidial_users SET preferred_codec='G729' WHERE user_id='6001';
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

(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"
Enter fullscreen mode Exit fullscreen mode

Verify changes applied:

asterisk -rx "sip show peers" | grep -A5 "carrier-a-main"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Reload and retry:

asterisk -rx "sip reload"
Enter fullscreen mode Exit fullscreen mode

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" 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Diagnosis:

asterisk -rx "codec show"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:

  1. Define your constraint: bandwidth, CPU, or quality
  2. Map carrier capabilities: Know what each carrier supports
  3. Configure hierarchical preferences: Global defaults with peer overrides
  4. Monitor continuously: Track CPU, bandwidth, and MOS scores
  5. Test thoroughly: Lab validation before production rollout
  6. 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.

Top comments (0)