How to get Asterisk DTMF input with Background Audio on Debian 12

To Get Asterisk DTMF Input With Background Audio On Debian 12

Introduction:

Dual-tone multi-frequency (DTMF) is the sounds or tones generated by a telephone when the numbers are pressed. These tones are transmitted with the voice channel. DTMF is used to control automated equipment and signal user intent, such as the number they wish to dial. Each key has two tones at specific frequencies.

Procedure:

Step 1: Check the OS version by using following command.

root@linuxhelp:~# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL=https://www.debian.org/ 
SUPPORT_URL=https://www.debian.org/support 
BUG_REPORT_URL=https://bugs.debian.org/

Step 2: Check the OS version by using following command.

root@linuxhelp:~# asterisk -V
Asterisk 20.4.0

Step 3: Go to the following location by using following command.

root@linuxhelp:~# cd /etc/asterisk/

Step 4: Open extensions.conf file and make the dialplan configuration to get dtmf input with background audio by using following command.

root@linuxhelp:/etc/asterisk# vim extensions.conf
[internal]
exten => 110,1,NoOp(Extension 110)
same=>n,Answer()
same=>n,Background(tt-monkeys)
same=>n,WaitExten(4)
same=>n,Dial(PJSIP/110/10)
same=>n,Playback(hangup-try-again)
same=>n,Hangup()

exten => i,1,NoOp(Invalid)

exten => t,1,NoOp(timeout)

exten => s,1,NoOp()
same=>n,Background(tt-monkeys)
same=>n,WaitExten(3)

exten => h,1,NoOp()

exten =>111,1,NoOp(Extension 111)
same=>n,Answer()
same=>n,Dial(PJSIP/111,10)
same=>n,Playback(hangup-try-again)
same=>n,Hangup()

exten => 112,1,NoOp(Extension 112)
same=>n,Answer()
same=>n,Dial(PJSIP/112,10)
same=>n,Playback(hangup-try-again)
same=>n,Hangup()

Step 5: Login to the Asterisk console by using following command.

root@linuxhelp:~# asterisk -rvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
Asterisk 20.4.0, Copyright (C) 1999 - 2022, Sangoma Technologies Corporation and others.
Created by Mark Spencer <markster@digium.com>
Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.
This is free software, with components licensed under the GNU General Public
License version 2 and other licenses; you are welcome to redistribute it under
certain conditions. Type 'core show license' for details.
=========================================================================
Connected to Asterisk 20.4.0 currently running on linuxhelp (pid = 1282)
linuxhelp*CLI>

Step 6: Reload the dialplan by using following command.

linuxhelp*CLI> dialplan reload
Dialplan reloaded.
    -- Time to scan old dialplan and merge leftovers back into the new: 0.000029 sec
    -- Time to restore hints and swap in new dialplan: 0.000004 sec
    -- Time to delete the old dialplan: 0.000006 sec
    -- Total time merge_contexts_delete: 0.000039 sec
    -- pbx_config successfully loaded 1 contexts (enable debug for details).

Step 7: Make the call to check by using MicroSIP application.

linuxhelp*CLI> 
    -- Executing [110@internal:1] NoOp("PJSIP/111-00000028", "Extension 110") in new stack
    -- Executing [110@internal:2] Answer("PJSIP/111-00000028", "") in new stack
       > 0x7f36e4011690 -- Strict RTP learning after remote address set to: 192.168.6.107:4032
    -- Executing [110@internal:3] BackGround("PJSIP/111-00000028", "tt-monkeys") in new stack
    -- <PJSIP/111-00000028> Playing 'tt-monkeys.ulaw' (language 'en')
       > 0x7f36e4011690 -- Strict RTP switching to RTP target address 192.168.6.107:4032 as source
       > 0x7f36e4011690 -- Strict RTP learning complete - Locking on source address 192.168.6.107:4032
    -- Executing [112@internal:1] NoOp("PJSIP/111-00000028", "Extension 112") in new stack
    -- Executing [112@internal:2] Answer("PJSIP/111-00000028", "") in new stack
    -- Executing [112@internal:3] Dial("PJSIP/111-00000028", "PJSIP/112,10") in new stack
    -- Called PJSIP/112
    -- PJSIP/112-00000029 is ringing
  == Spawn extension (internal, 112, 3) exited non-zero on 'PJSIP/111-00000028'
    -- Executing [h@internal:1] NoOp("PJSIP/111-00000028", "") in new stack

Step 8: Again Make the call to check the invalid DTMF input by using MicroSIP application.

linuxhelp*CLI> 
    -- Executing [110@internal:1] NoOp("PJSIP/111-0000002a", "Extension 110") in new stack
    -- Executing [110@internal:2] Answer("PJSIP/111-0000002a", "") in new stack
       > 0x7f37280286e0 -- Strict RTP learning after remote address set to: 192.168.6.107:4034
    -- Executing [110@internal:3] BackGround("PJSIP/111-0000002a", "tt-monkeys") in new stack
    -- <PJSIP/111-0000002a> Playing 'tt-monkeys.ulaw' (language 'en')
       > 0x7f37280286e0 -- Strict RTP switching to RTP target address 192.168.6.107:4034 as source
    -- Invalid extension '2' in context 'internal' on PJSIP/111-0000002a
    -- Executing [i@internal:1] NoOp("PJSIP/111-0000002a", "Invalid") in new stack
    -- Auto fallthrough, channel 'PJSIP/111-0000002a' status is 'UNKNOWN'
    -- Executing [h@internal:1] NoOp("PJSIP/111-0000002a", "") in new stack

Step 9: Open extensions.conf file and make dialplan configuration to check the empty DTMF input by using following command.

root@linuxhelp:/etc/asterisk# vim extensions.conf
[internal]
exten => 110,1,NoOp(Extension 110)
same=>n,Answer()
same=>n,Background(tt-monkeys)
same=>n,WaitExten(4)
same=>n,Goto(s,1)
same=>n,Dial(PJSIP/110/10)
same=>n,Playback(hangup-try-again)
same=>n,Hangup()

exten => i,1,NoOp(Invalid)

exten => t,1,NoOp(timeout)

exten => s,1,NoOp()
same=>n,Background(tt-monkeys)
same=>n,WaitExten(3)

exten => h,1,NoOp()

exten =>111,1,NoOp(Extension 111)
same=>n,Answer()
same=>n,Dial(PJSIP/111,10)
same=>n,Playback(hangup-try-again)
same=>n,Hangup()

exten => 112,1,NoOp(Extension 112)
same=>n,Answer()
same=>n,Dial(PJSIP/112,10)
same=>n,Playback(hangup-try-again)
same=>n,Hangup()

Step 10: Reload the dialplan by using following command.

linuxhelp*CLI> dialplan reload
Dialplan reloaded.
    -- Time to scan old dialplan and merge leftovers back into the new: 0.000003 sec
    -- Time to restore hints and swap in new dialplan: 0.000005 sec
    -- Time to delete the old dialplan: 0.000006 sec
    -- Total time merge_contexts_delete: 0.000014 sec
    -- pbx_config successfully loaded 1 contexts (enable debug for details).

Step 11: Make the call to check the empty DTMF input by using MicroSIP application.

linuxhelp*CLI> 
    -- Executing [110@internal:1] NoOp("PJSIP/112-0000002b", "Extension 110") in new stack
    -- Executing [110@internal:2] Answer("PJSIP/112-0000002b", "") in new stack
       > 0x7f36e40445c0 -- Strict RTP learning after remote address set to: 192.168.6.107:4042
    -- Executing [110@internal:3] BackGround("PJSIP/112-0000002b", "tt-monkeys") in new stack
    -- <PJSIP/112-0000002b> Playing 'tt-monkeys.ulaw' (language 'en')
       > 0x7f36e40445c0 -- Strict RTP switching to RTP target address 192.168.6.107:4042 as source
       > 0x7f36e40445c0 -- Strict RTP learning complete - Locking on source address 192.168.6.107:4042
    -- Executing [110@internal:4] WaitExten("PJSIP/112-0000002b", "4") in new stack
    -- Timeout on PJSIP/112-0000002b, continuing...
    -- Executing [110@internal:5] Goto("PJSIP/112-0000002b", "s,1") in new stack
    -- Goto (internal,s,1)
    -- Executing [s@internal:1] NoOp("PJSIP/112-0000002b", "") in new stack
    -- Executing [s@internal:2] BackGround("PJSIP/112-0000002b", "tt-monkeys") in new stack
    -- <PJSIP/112-0000002b> Playing 'tt-monkeys.ulaw' (language 'en')
    -- Executing [s@internal:3] WaitExten("PJSIP/112-0000002b", "3") in new stack
    -- Timeout on PJSIP/112-0000002b, going to 't'
    -- Executing [t@internal:1] NoOp("PJSIP/112-0000002b", "timeout") in new stack
    -- Auto fallthrough, channel 'PJSIP/112-0000002b' status is 'UNKNOWN'
    -- Executing [h@internal:1] NoOp("PJSIP/112-0000002b", "") in new stack

Conclusion:

We have reached the end of this article. In this guide, we have walked you through the steps required to get Asterisk DTMF input with Background Audio on Debian 12. Your feedback is much welcome.

FAQ
Q
What are some common issues with DTMF input and background audio?
A
DTMF digits not recognized: Ensure your SIP channels are configured correctly for DTMF mode (RFC2833 or inband) and that relaxdtmf=yes is enabled if needed.
Audio overlapping with DTMF tones: Adjust the audio file timings or use silence padding as mentioned above.
Timeout while waiting for input: Set appropriate timeouts and provide clear instructions to callers.
Q
Can I capture DTMF input while continuing to play the background audio?
A
Yes, you can use applications like MixMon or custom dialplan logic to achieve this. Here's an example:
exten => s,1,Answer()
exten => s,n,MixMon(audio.wav, "", "|Read(digits,5)")
exten => s,n,GotoIf("$digits?1=sales")
exten => s,n,GotoIf("$digits?2=support")
exten => s,n,Playback(invalid_input)
exten => s,n,Hangup
This example plays the audio.wav file while also capturing the first 5 DTMF digits. It then routes the call based on the captured digits.
Q
How do I avoid DTMF tones interrupting the audio playback?
A
Asterisk offers several options to prevent DTMF tones from cutting off the audio:
relaxdtmf=yes: Set this option in your SIP channel configuration to allow DTMF digits to be recognized even if they overlap slightly with the audio playback.
mohdigitstop=1: Set this option in your music on hold configuration to pause the music when a DTMF digit is received.
mohprepend=""/mohpostpend="": Use these options to add silence before and after your music on hold file, giving callers a brief window to press a key without interrupting the audio.
Q
How can I capture DTMF input from a caller while playing background audio in Asterisk?
A
There are several ways to achieve this in Asterisk:
Background Application: Use the Background application with the dtmfprompt option. This plays the audio file and simultaneously waits for DTMF input. The captured digits are stored in a variable that you can use in your dialplan logic.
Read Application: Use the Read application after playing the audio file. This waits for a specific number of DTMF digits or a timeout and stores them in a variable.
MixMon Application: Use the MixMon application to mix the background audio with a prompt asking for user input. You can then capture the pressed digits using either Background or Read.
Q
What is the use of the Asterisk DTMF?
A
Allow telephones to indicate which number is being pressed by its operator