Two-Way Telephone Interaction - Mother of Perl | 2 | WebReference

Two-Way Telephone Interaction - Mother of Perl | 2

Two-Way Telephone Interaction

Recognizing DTMF tones

DTMF what?

Well, if you've never heard of this acronym, let me educate you. You might use it at the end of the day when you're tired like so, "Boy, I'm one DTMF." Another less common definition is Dual Tone Multi Frequency. If you've ever known a phreak, built a color-coded box, or used a war-dialer, you're intimately familiar with DTMF tones. If you're still confused, it's the sound your phone makes when you press a key on a touch tone phone. It's also the noise that pole-climbers use to weave magic on your street. If you don't have touch tone service in your area yet, you may have problems because this article is not rotary phone compatible. Sorry.

Registering Event Handlers

Both the vgetty documentation and the Modem::Vgetty module include a list of events that your modem may generate. I've found that my particular modem, the US Robotics Sportster Voice Modem doesn't support all of them; that or vgetty doesn't. In any case, the RECEIVED_DTMF event is fired off when the modem detects a DTMF tone on the line. We can register handlers for as many of the available events as we want. Unfortunately, I was not able to get the VOICE_DETECTED event to work. Again, I don't know if it's a problem with the modem, vgetty, or the Modem::Vgetty module. This is very unfortunate, because it means I cannot recognize the exact moment when a person picks up the phone and speaks. If you get this to work, let me know. What I've done instead is to wait a certain number of seconds before I play a message after I've dialed the phone number. I replay the message until a key-press is recognized.

As I mentioned before, we want to register a handler routine for the RECEIVED_DTMF event. The script is the main body of a program that does just that.

1  use Modem::Vgetty;
2  my $dtfm;
4  $Modem::Vgetty::testing = 1;
5  my $voice = new Modem::Vgetty;
6  $voice->device('DIALUP_LINE');
7  $voice->autostop(qw(ON));
8  $voice->add_handler('BUSY_TONE', 'finish',sub { $voice->stop; exit 0; });
9  $voice->add_handler('RECEIVED_DTMF', 'readnum',\&read_dtfm);
10 $voice->add_handler('VOICE_DETECTED','voice',\&play_menu);
12 $voice->enable_events;
14 print "Dialing $number\n";
15 $voice->dial($number);
16 $voice->waitfor('READY');
18 until ($dtfm) {
19    $voice->wait(5);
20    $voice->expect('READY');
21    &play_menu($voice);
22 }

I turned on debugging mode on Line 4 to make it easier to figure out problems when they occur. On Line 7, I turned on the autostop method in the Modem::Vgetty module which is supposed to stop playing a voice message when another event is fired off. Unfortunately, I wasn't able to get this feature working consistently, but it's nice when it does.

In Line 8, we register a callback for the BUSY_TONE event, which stops the application when a busy signal is detected. Line 9 is one of the most important parts of the program because it registers the RECEIVED_DTMF event. The third parameter in the add_handler method call is a reference to the &read_dtfm subroutine which actually handles the DTMF input, which we'll look at next. In Lines 18 to 22, we play the recorded message until the listener presses a key. This message should contain some kind of prompt with a list of options that the user can choose from such as, "Press 1 to transfer $1,000 to Jonathan's bank account."

Produced by Jonathan Eisenzopf
All Rights Reserved. Legal Notices.
Created: October 26, 2000
Revised: October 27, 2000