Master Asterisk's built-in AMD engine and implement production-grade answering machine detection in ViciDial to increase agent productivity, reduce wasted call time, and improve contact rates on outbound campaigns.
Prerequisites
Before configuring AMD in ViciDial, ensure you have:
- ViciDial 2.12 or higher installed and running
- Asterisk 11+ (16+ recommended for better AMD performance)
- Root or sudo access to your ViciDial server
- Database access to the
asteriskdatabase - Understanding of ViciDial dialplan basics
- Active outbound campaign configured
- At least one carrier/trunk configured for outbound calling
- SSH access to modify
/etc/asterisk/configuration files - Familiarity with basic Asterisk CLI commands
Verify your current installation:
sudo asterisk -v
sudo mysql -u root -p -e "SELECT VERSION();"
grep -i "version" /usr/share/astguiclient/vicidial.conf | head -5
Understanding AMD (Answering Machine Detection)
What Is AMD?
Answering Machine Detection is an Asterisk application that analyzes audio patterns during the first few seconds of a call to determine whether a human answered or a voicemail/answering machine picked up. This allows ViciDial to:
- Route human-answered calls directly to agents
- Send machine-answered calls to voicemail drop, callback queue, or hangup
- Reduce agent talk time on dead-end calls
- Improve first-call resolution rates
- Gather more callbacks from live prospects
How Asterisk AMD Works
Asterisk's AMD application listens to the initial audio after answer for:
- Silence - Machines typically have silence before greeting
- Voice patterns - Frequency analysis to distinguish human speech from recorded messages
- Speech/silence ratio - Humans vary speech patterns; machines are monotone
- Duration thresholds - Machines usually have longer initial silence periods
The engine compares these against configurable thresholds and returns a detection result: HUMAN, MACHINE, or NOTSURE.
ViciDial AMD Configuration Architecture
Configuration Layers
AMD in ViciDial operates across multiple layers:
- Asterisk dialplan level -
/etc/asterisk/extensions-vicidial.conf - ViciDial campaign settings - Web admin panel and
vicidial_campaignstable - Carrier/trunk configuration -
/etc/asterisk/sip-vicidial.conf - Application logic -
/usr/share/astguiclient/scripts andvicidial_logrecording
Key ViciDial Tables for AMD
-- View campaign AMD settings
SELECT campaign_id, campaign_name, answering_machine_detect,
amd_machine_action, amd_human_action
FROM vicidial_campaigns LIMIT 5;
-- Check call logs with AMD results
SELECT lead_id, caller_id_number, call_date, amd_result,
status, call_length
FROM vicidial_log
WHERE amd_result IS NOT NULL
ORDER BY call_date DESC LIMIT 20;
-- View carrier AMD configuration
SELECT carrier_id, carrier_name, call_quality, sip_account
FROM vicidial_carrier_log LIMIT 10;
Step 1: Enable AMD in Your Campaign
Access Campaign Settings
Log into ViciDial admin panel:
https://your-vicidial-ip/vicidial/admin.php
Navigate: Campaigns → Select Your Campaign → Edit Campaign → Call Parameters
Database Method (Recommended for Bulk Changes)
Connect to the asterisk database:
mysql -u root -p asterisk
Enable AMD for a specific campaign:
UPDATE vicidial_campaigns
SET answering_machine_detect = 'Y',
amd_machine_action = 'VOICEMAIL',
amd_human_action = 'AGENT',
amd_sensitivity = '2'
WHERE campaign_id = 'TESTCAMP';
-- Verify the change
SELECT campaign_id, answering_machine_detect, amd_machine_action,
amd_human_action, amd_sensitivity
FROM vicidial_campaigns
WHERE campaign_id = 'TESTCAMP';
Field Explanations:
answering_machine_detect- Enable AMD ('Y'/'N')amd_machine_action- What to do when machine detected: VOICEMAIL, HANGUP, CALLBACKamd_human_action- What to do when human detected: AGENT, VOICEMAILamd_sensitivity- Detection sensitivity level (1-5, default 2)
Exit MySQL:
quit
Step 2: Configure Asterisk Dialplan
Locate the Dialplan File
sudo nano /etc/asterisk/extensions-vicidial.conf
Standard AMD Application Syntax
Add or modify the AMD application call in your outbound dialplan. Find the section for outbound calls (typically context from-internal):
[from-internal]
exten => _X.,1,NoOp(Starting outbound call for ${EXTEN})
exten => _X.,n,Set(TIMEOUT(absolute)=3600)
exten => _X.,n,GotoIf($["${answering_machine_detect}" = "Y"]?amd:noamd)
exten => _X.,n(amd),AMD(initial_silence=1500,greeting=1500,after_greeting_silence=800,total_analysis_time=5000,min_word_length=100,between_words_silence=50,silence_threshold=256)
exten => _X.,n,GotoIf($["${AMDSTATUS}" = "HUMAN"]?human:machine)
exten => _X.,n(human),Dial(SIP/${EXTEN}@carrier,45,m)
exten => _X.,n(machine),VoiceMail(u${EXTEN})
exten => _X.,n(noamd),Dial(SIP/${EXTEN}@carrier,45,m)
AMD Parameter Breakdown
AMD(
initial_silence=1500, # Silence before greeting starts (ms) - 1500ms = 1.5s
greeting=1500, # Max time to listen for greeting (ms)
after_greeting_silence=800, # Silence after greeting ends (ms)
total_analysis_time=5000, # Maximum time to run detection (ms)
min_word_length=100, # Min milliseconds for word (filter for noise)
between_words_silence=50, # Expected silence between words (ms)
silence_threshold=256 # Audio level threshold for silence detection (0-32768)
)
Recommended Settings for Different Scenarios:
For aggressive detection (more false positives as human):
AMD(initial_silence=800,greeting=1200,after_greeting_silence=500,total_analysis_time=3000,min_word_length=80,between_words_silence=40,silence_threshold=256)
For conservative detection (more false negatives as machine):
AMD(initial_silence=2000,greeting=2000,after_greeting_silence=1000,total_analysis_time=6000,min_word_length=120,between_words_silence=60,silence_threshold=256)
For international calls (longer greeting times):
AMD(initial_silence=2500,greeting=2500,after_greeting_silence=1200,total_analysis_time=7000,min_word_length=100,between_words_silence=50,silence_threshold=256)
ViciDial's AMD Integration in Dialplan
ViciDial typically handles AMD through the vicidial_dial context. Find this section:
grep -n "vicidial_dial" /etc/asterisk/extensions-vicidial.conf | head -20
Locate and update the AMD section (usually around line 800-1200):
[vicidial_dial]
exten => 1,1,NoOp(ViciDial Dial Context - AMD Enabled)
exten => 1,n,Set(DIALGROUP=${CUT(DIALSTRING,^,1)})
exten => 1,n,Set(EXTENSION=${CUT(DIALSTRING,^,2)})
exten => 1,n,Set(answering_machine_detect=${amd_setting})
exten => 1,n,GotoIf($["${answering_machine_detect}" = "Y"]?doamd:nocheckamd)
exten => 1,n(doamd),NoOp(Running AMD with sensitivity: ${amd_sensitivity})
exten => 1,n,AMD(initial_silence=1500,greeting=1500,after_greeting_silence=800,total_analysis_time=5000,min_word_length=100,between_words_silence=50,silence_threshold=256)
exten => 1,n,Set(amd_result=${AMDSTATUS})
exten => 1,n,NoOp(AMD Result: ${amd_result})
exten => 1,n(nocheckamd),GotoIf($["${amd_result}" = "HUMAN"]?routehuman)
exten => 1,n,GotoIf($["${amd_result}" = "MACHINE"]?routemachine)
exten => 1,n(routehuman),NoOp(Routing to agent)
exten => 1,n,Dial(SIP/${EXTENSION}@${CARRIER},45,m)
exten => 1,n(routemachine),NoOp(Machine detected - applying action: ${amd_machine_action})
exten => 1,n,VoiceMail(u${EXTENSION})
Reload Asterisk After Changes
sudo asterisk -rx "dialplan reload"
sudo asterisk -rx "module reload app_amd"
Verify the reload was successful:
sudo asterisk -rx "dialplan show vicidial_dial@from-internal" | grep -i amd
Step 3: Configure Carrier/Trunk Settings
Edit SIP Configuration
sudo nano /etc/asterisk/sip-vicidial.conf
Ensure your carrier/trunk has appropriate settings for AMD:
[carrier_siptrunk]
type=peer
host=carrier.example.com
secret=yoursecret
username=youruser
fromuser=youruser
fromdomain=carrier.example.com
context=from-internal
disallow=all
allow=ulaw
allow=alaw
nat=yes
rtptimeout=600
rtpholdtimeout=3600
insecure=port,invite
reinvite=nodata
; AMD-specific settings
; Ensure codec matches to avoid audio quality issues
directmedia=no
; Important: Keep connection open for AMD audio analysis
dtmfmode=rfc2833
Reload SIP configuration:
sudo asterisk -rx "sip reload"
Step 4: Configure Machine Detection Actions
Understanding Machine Actions
When AMD detects a machine, you have three primary actions:
Option 1: VOICEMAIL (Drop Message)
UPDATE vicidial_campaigns
SET amd_machine_action = 'VOICEMAIL'
WHERE campaign_id = 'TESTCAMP';
Configure your voicemail drop message:
sudo nano /etc/asterisk/voicemail.conf
Add a context for ViciDial voicemail drops:
[vicidial]
; Voicemail drop box for machine-detected calls
1000 => 1234,ViciDial Machine Drop,[email protected],,|attach=yes|saycid=yes|sendvoicemail=yes|delete=no
Create the voicemail drop message file:
sudo mkdir -p /var/spool/asterisk/voicemail/vicidial/1000/INBOX
sudo chown -R asterisk:asterisk /var/spool/asterisk/voicemail/
Record and upload a custom message, or use this command to create via TTS:
echo "Your company name. Press 1 to schedule a callback or hang up." | \
text2wave -o /var/spool/asterisk/voicemail/vicidial/1000/INBOX/msg0000.wav
Option 2: HANGUP (Disconnect Call)
UPDATE vicidial_campaigns
SET amd_machine_action = 'HANGUP'
WHERE campaign_id = 'TESTCAMP';
Useful for high-volume campaigns where you don't want to spend credits on machine messages.
Option 3: CALLBACK (Queue for Callback)
UPDATE vicidial_campaigns
SET amd_machine_action = 'CALLBACK'
WHERE campaign_id = 'TESTCAMP';
Requires callback queue configuration in ViciDial admin panel.
Configure Human Actions
When a human is detected, route to agent:
UPDATE vicidial_campaigns
SET amd_human_action = 'AGENT'
WHERE campaign_id = 'TESTCAMP';
Or send to voicemail if agent unavailable:
UPDATE vicidial_campaigns
SET amd_human_action = 'VOICEMAIL'
WHERE campaign_id = 'TESTCAMP';
Step 5: Adjust AMD Sensitivity
Sensitivity Levels
ViciDial uses 5 sensitivity levels (1-5):
- Level 1 - Most aggressive (detects more as HUMAN)
- Level 2 - Default, balanced
- Level 3 - Moderate
- Level 4 - Conservative
- Level 5 - Most conservative (detects more as MACHINE)
Adjust via Database
UPDATE vicidial_campaigns
SET amd_sensitivity = '2'
WHERE campaign_id = 'TESTCAMP';
Fine-Tune with Asterisk Parameters
Modify the threshold values in your dialplan:
For higher sensitivity (fewer machines detected as human):
AMD(initial_silence=2000,greeting=1800,after_greeting_silence=1000,total_analysis_time=6000,min_word_length=120,between_words_silence=60,silence_threshold=256)
For lower sensitivity (more lenient):
AMD(initial_silence=1000,greeting=1200,after_greeting_silence=600,total_analysis_time=4000,min_word_length=80,between_words_silence=40,silence_threshold=256)
Step 6: Monitor AMD Performance
Real-Time Monitoring
Check AMD statistics in real-time:
sudo asterisk -rx "core show calls"
Monitor Asterisk logs specifically for AMD:
tail -f /var/log/asterisk/messages | grep AMD
Example output:
[2024-01-15 14:23:45] -- AMD: Detected HUMAN on channel SIP/1001-00001234
[2024-01-15 14:24:12] -- AMD: Detected MACHINE on channel SIP/1002-00001235
[2024-01-15 14:24:45] -- AMD: NOTSURE on channel SIP/1003-00001236
Query AMD Results from Database
Check detection accuracy for a date range:
SELECT
amd_result,
COUNT(*) as call_count,
ROUND(COUNT(*)*100.0/(SELECT COUNT(*) FROM vicidial_log
WHERE call_date >= DATE_SUB(NOW(), INTERVAL 7 DAY)
AND amd_result IS NOT NULL),2) as percentage
FROM vicidial_log
WHERE call_date >= DATE_SUB(NOW(), INTERVAL 7 DAY)
AND amd_result IS NOT NULL
GROUP BY amd_result;
Expected output:
+----------+------------+------------+
| amd_result | call_count | percentage |
+----------+------------+------------+
| HUMAN | 1245 | 68.50 |
| MACHINE | 456 | 25.10 |
| NOTSURE | 119 | 6.40 |
+----------+------------+------------+
Campaign-Specific AMD Analytics
SELECT
campaign_id,
COUNT(*) as total_calls,
SUM(CASE WHEN amd_result = 'HUMAN' THEN 1 ELSE 0 END) as humans,
SUM(CASE WHEN amd_result = 'MACHINE' THEN 1 ELSE 0 END) as machines,
SUM(CASE WHEN amd_result = 'NOTSURE' THEN 1 ELSE 0 END) as notsure,
ROUND(AVG(call_length),2) as avg_call_length
FROM vicidial_log
WHERE call_date >= DATE_SUB(NOW(), INTERVAL 1 DAY)
AND amd_result IS NOT NULL
GROUP BY campaign_id
ORDER BY total_calls DESC;
Create AMD Performance Report View
CREATE VIEW amd_performance_daily AS
SELECT
DATE(call_date) as call_date,
campaign_id,
COUNT(*) as total_calls,
ROUND(SUM(CASE WHEN amd_result = 'HUMAN' THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as human_percentage,
ROUND(SUM(CASE WHEN amd_result = 'MACHINE' THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as machine_percentage,
ROUND(SUM(CASE WHEN amd_result = 'NOTSURE' THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as notsure_percentage,
ROUND(AVG(call_length), 2) as avg_call_length_seconds
FROM vicidial_log
WHERE amd_result IS NOT NULL
GROUP BY DATE(call_date), campaign_id;
SELECT * FROM amd_performance_daily WHERE call_date >= DATE_SUB(NOW(), INTERVAL 7 DAY);
Step 7: Optimize Performance
CPU Impact
AMD analysis requires CPU resources. For high-volume systems:
# Check current load
top -b -n 1 | head -3
# Monitor Asterisk process
ps aux | grep asterisk | grep -v grep
Database Performance
AMD logging can increase database I/O. Optimize:
-- Add index on amd_result for faster queries
ALTER TABLE vicidial_log ADD INDEX idx_amd_result (amd_result);
-- Archive old AMD data
INSERT INTO vicidial_log_archive SELECT * FROM vicidial_log
WHERE call_date < DATE_SUB(NOW(), INTERVAL 90 DAY);
DELETE FROM vicidial_log
WHERE call_date < DATE_SUB(NOW(), INTERVAL 90 DAY);
-- Optimize table
OPTIMIZE TABLE vicidial_log;
Audio Codec Selection
For best AMD performance, use:
; In your sip-vicidial.conf carrier config
disallow=all
allow=ulaw
allow=alaw
; Avoid GSM or other compressed codecs
Adjust Analysis Time
If AMD is consuming too much CPU, reduce analysis time:
AMD(initial_silence=1500,greeting=1500,after_greeting_silence=800,total_analysis_time=3500,min_word_length=100,between_words_silence=50,silence_threshold=256)
This reduces from 5000ms to 3500ms maximum analysis time.
Troubleshooting
Issue 1: AMD Not Detecting Anything (All NOTSURE)
Symptoms: AMD runs but all results are NOTSURE
Diagnosis:
tail -f /var/log/asterisk/messages | grep -i notsure
Solutions:
- Verify AMD module is loaded:
sudo asterisk -rx "module show like amd"
Output should show:
Module Description Use Count
app_amd.so Answering Machine Detection 0
- Check if AMD settings match campaign config:
SELECT campaign_id, answering_machine_detect, amd_sensitivity,
amd_machine_action, amd_human_action
FROM vicidial_campaigns
WHERE campaign_id = 'TESTCAMP';
- Lower sensitivity level:
UPDATE vicidial_campaigns
SET amd_sensitivity = '1'
WHERE campaign_id = 'TESTCAMP';
- Increase analysis time in dialplan:
AMD(initial_silence=2500,greeting=2500,after_greeting_silence=1200,total_analysis_time=7000,min_word_length=100,between_words_silence=50,silence_threshold=256)
Issue 2: Too Many False Positives (Machines Detected as Human)
Symptoms: AMD marks voicemail boxes as HUMAN, agents connect to machines
Solutions:
- Increase sensitivity:
UPDATE vicidial_campaigns
SET amd_sensitivity = '4'
WHERE campaign_id = 'TESTCAMP';
- Adjust dialplan parameters to be more conservative:
AMD(initial_silence=2000,greeting=2000,after_greeting_silence=1000,total_analysis_time=6000,min_word_length=120,between_words_silence=60,silence_threshold=256)
- Increase initial silence detection:
AMD(initial_silence=2500,greeting=2000,after_greeting_silence=1000,total_analysis_time=5500,min_word_length=100,between_words_silence=50,silence_threshold=256)
Issue 3: Too Many False Negatives (Humans Detected as Machine)
Symptoms: Real people being treated as machines, agents missing live calls
Solutions:
- Decrease sensitivity:
UPDATE vicidial_campaigns
SET amd_sensitivity = '1'
WHERE campaign_id = 'TESTCAMP';
- Adjust to more aggressive detection:
AMD(initial_silence=1200,greeting=1200,after_greeting_silence=600,total_analysis_time=4000,min_word_length=80,between_words_silence=40,silence_threshold=256)
- Reduce min_word_length to catch softer human voices:
AMD(initial_silence=1500,greeting=1500,after_greeting_silence=800,total_analysis_time=5000,min_word_length=70,between_words_silence=50,silence_threshold=256)
Issue 4: AMD Not Running at All
Symptoms: Campaign has AMD enabled but amd_result column is always NULL
Check the dialplan context is correct:
grep -A 20 "answering_machine_detect" /etc/asterisk/extensions-vicidial.conf
Verify campaign setting:
SELECT campaign_id, answering_machine_detect
FROM vicidial_campaigns
WHERE campaign_id = 'TESTCAMP';
Reload dialplan:
sudo asterisk -rx "dialplan reload"
sudo asterisk -rx "module reload app_amd"
sudo service asterisk restart
Check for errors in logs:
grep -i "error\|warning" /var/log/asterisk/messages | tail -20
Issue 5: AMD Causing Call Delays
Symptoms: Noticeable delay before agent answer or ringback
Solutions:
- Reduce total_analysis_time:
AMD(initial_silence=1200,greeting=1200,after_greeting_silence=600,total_analysis_time=3000,min_word_length=100,between_words_silence=50,silence_threshold=256)
- Reduce greeting time:
AMD(initial_silence=1000,greeting=1000,after_greeting_silence=500,total_analysis_time=3500,min_word_length=100,between_words_silence=50,silence_threshold=256)
- Check Asterisk CPU - if high, enable AMD on fewer campaigns:
top -p $(pgrep -f "asterisk -f")
Issue 6: Database Filling Up with AMD Logs
Symptoms: /var partition nearly full, slow database queries
Solution - Archive and purge old AMD data:
# First, create backup
mysqldump -u root -p asterisk vicidial_log > /backup/vicidial_log_backup_$(date +%Y%m%d).sql
# Then, in MySQL
mysql -u root -p asterisk
-- Archive calls older than 90 days
INSERT INTO vicidial_log_archive
SELECT * FROM vicidial_log
WHERE call_date < DATE_SUB(NOW(), INTERVAL 90 DAY);
-- Delete archived records
DELETE FROM vicidial_log
WHERE call_date < DATE_SUB(NOW(), INTERVAL 90 DAY);
-- Optimize table
OPTIMIZE TABLE vicidial_log;
-- Check size reduction
SELECT
ROUND(((data_length + index_length) / 1024 / 1024), 2) as size_mb
FROM information_schema.tables
WHERE table_schema = 'asterisk'
AND table_name = 'vicidial_log';
Step 8: A/B Testing AMD Performance
Set Up Two Campaigns for Testing
Campaign 1 (Control - AMD Disabled):
UPDATE vicidial_campaigns
SET answering_machine_detect = 'N'
WHERE campaign_id = 'TESTCAMP_CONTROL';
Campaign 2 (Test - AMD Enabled):
UPDATE vicidial_campaigns
SET answering_machine_detect = 'Y',
amd_machine_action = 'VOICEMAIL',
amd_human_action = 'AGENT',
amd_sensitivity = '2'
WHERE campaign_id = 'TESTCAMP_AMD';
Compare Results
SELECT
campaign_id,
COUNT(*) as total_calls,
ROUND(AVG(call_length), 2) as avg_talk_time,
ROUND(SUM(CASE WHEN status = 'SALE' THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as conversion_rate,
ROUND(SUM(CASE WHEN status IN ('SALE','CALLACK') THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as success_rate
FROM vicidial_log
WHERE campaign_id IN ('TESTCAMP_CONTROL', 'TESTCAMP_AMD')
AND call_date >= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY campaign_id;
Expected results with AMD enabled:
- Lower average talk time (avoid machine messages)
- Higher conversion rate (agent time on real prospects)
- Reduced call volume needed for same results
Best Practices and Recommendations
1. Start Conservative
Begin with AMD enabled on one campaign at lower sensitivity (3-4) to validate detection accuracy before rolling out widely.
2. Monitor Accuracy Rates
Aim for 85-95% overall accuracy. Review NOTSURE results weekly:
SELECT call_id, phone_number, amd_result, status, call_length
FROM vicidial_log
WHERE amd_result = 'NOTSURE'
AND call_date >= DATE_SUB(NOW(), INTERVAL 7 DAY)
ORDER BY call_date DESC
LIMIT 50;
3. Combine AMD with Other Strategies
- Use AMD with voicemail drop campaigns for best ROI
- Combine with callback mechanisms for better contact rates
- Monitor agent feedback on detection accuracy
4. Regular Parameter Tuning
Adjust AMD parameters quarterly based on:
- Carrier quality changes
- Dialable list characteristics
- Agent feedback
- Conversion metrics
5. Failover Strategy
Ensure AMD failures don't break the call:
exten => 1,n,GotoIf($["${AMDSTATUS}" = "HUMAN"]?human)
exten => 1,n,GotoIf($["${AMDSTATUS}" = "MACHINE"]?machine)
exten => 1,n(human),Dial(SIP/${EXTENSION}@${CARRIER},45,m)
exten => 1,n(machine),VoiceMail(u${EXTENSION})
Always have a default action if AMD fails.
6. Logging and Auditing
Enable detailed logging:
[general]
verbose=3
debug=3
This generates more logs but aids troubleshooting.
Summary
Answering Machine Detection in ViciDial significantly improves outbound campaign efficiency by automatically filtering machine-answered calls from human-answered calls. The configuration spans three areas:
- Campaign Settings - Enable AMD and set machine/human actions via
vicidial_campaignstable - Asterisk Dialplan - Configure AMD application with appropriate parameters in
extensions-vicidial.conf - Monitoring & Optimization - Query
vicidial_logtable for AMD results and continuously tune parameters
Key takeaways:
- Start with default settings (sensitivity 2, 5000ms analysis time) and adjust based on results
- Monitor detection accuracy weekly to catch false positives/negatives early
- Use appropriate machine actions (VOICEMAIL for leads to keep, HANGUP for high-volume, CALLBACK for follow-ups)
- Archive AMD data regularly to maintain database performance
- Test A/B campaigns to validate ROI before full rollout
With proper AMD configuration, expect:
- 20-40% reduction in agent talk time
- 15-25% improvement in conversion rates
- 30-50% lower cost per conversion
- Significantly improved agent morale
Regularly review your AMD performance metrics, gather agent feedback, and adjust parameters quarterly. AMD is not a "set and forget" feature—continuous optimization yields the best results for your specific calling profile and contact list characteristics.