What happens when you press 5 on a phone call
A key press is two sine waves. On a modern VoIP call it is usually not sound at all, but a small packet that says which key and for how long. A walk from the 1960 Bell Labs design to RFC 4733, with the codec test that drops digits.

You call a support line. A voice says “press 1 for billing”. You press 1, and something on the other end knows. That link has carried the same sound since 1963, and on a modern internet call it often carries no sound at all. This is how it works, from the tone to the packet.
A key is two tones#
Each key plays two sine waves at once. One from a low group, one from a high group. The pair is the code. This is where the name comes from: dual-tone multi-frequency, DTMF.
Press 5 and the phone sends 770 Hz and 1336 Hz together. Press 9 and it sends 852 and 1477. Sixteen keys, eight frequencies, and every key is one unique pair. The fourth column (A, B, C, D) exists in the standard but almost no phone has those keys.
Here are the two tones for key 5, and their sum. The sum is the actual sound that leaves the phone.
The sum looks messy, but it holds exactly two frequencies and nothing else. Run it through a frequency analysis and you get two clean spikes, one per tone.
Why these exact frequencies#
The frequencies look random. They are not. They come from a 1960 Bell Labs paper, and the design problem was a hard one: a person’s voice must almost never sound like a key.
A vowel is a buzz from the vocal cords, shaped by the mouth, rich in harmonics. So speech is full of frequency pairs with simple whole-number ratios, like 2:1 or 3:2. The trick was to pick eight frequencies whose pairs avoid those ratios. The spacing between neighbours is a fixed ratio of about 1.1 (check: 770 / 697 = 1.105, 852 / 770 = 1.106). That spacing is what keeps the pairs clear of common vowel harmonics.
Two details I did not expect:
- The original 1960 high group topped out at 1477 Hz with a different fourth frequency. The 1633 Hz we use today replaced it later.
- The set was placed to interleave with the frequencies of the phone’s own ringer. Any shifted set would have worked against vowels equally well. Bell chose this one to fit around the bell.
The first Touch-Tone service went live on 18 November 1963, in Carnegie and Greensburg, Pennsylvania, with ten buttons. The star and hash came later.
How the other end hears a digit#
The receiver has to answer one question many times a second: are two of my eight frequencies present right now, and only two?
The textbook tool is the Goertzel algorithm. A full frequency analysis computes every frequency. Goertzel computes just one, with a tiny recursive filter that runs one sample at a time. For eight known frequencies it is far cheaper than the alternative, and it needs no buffer. That is why it has run on cheap telephony hardware for decades.
Reading the real code is more interesting than the theory. Asterisk, the open-source phone system, uses a block of 102 samples, not the 205 that every tutorial quotes. It tunes each filter to the exact tone frequency, and it guards against voice with an energy test: the two tones must hold a large share of the block’s total energy, since speech smears energy across many frequencies while a real key press concentrates it in two.
There is a real cost to listening for more keys. An old AT&T spec allowed one false digit per 3000 calls when listening for 0 to 9, but one per 1500 when listening for all sixteen. Every extra key you accept is another thing a human voice can accidentally trip. This has a name: talk-off, speech that the receiver reads as a digit.
The part that surprised me: on VoIP, the digit is usually not sound#
So far this is the old phone network, where the tones travel as audio down a copper line. On an internet call it mostly does not work that way, and the reason is the codec.
A codec compresses voice to save bandwidth. Modern ones (G.729, AMR, low-bitrate Opus) do it by modelling a human voice: a vocal tract filter driven by vocal cords. A DTMF pair is two pure sine waves, which is not a voice at all. The codec spends its few bits trying to fit a voice-shaped model to something that is not a voice, and the tones come out distorted. The two tones drift in relative level, and the receiver stops recognising them.
I tested this. I generated all sixteen keys, pushed them through real codecs, and ran a detector on the far side.
original : 0123456789*#ABCD
G.711 u-law : 0123456789*#ABCD all 16 survive
G.729 : 0245789*#ACD 1, 3, 6 and B lost
G.711 is the old uncompressed codec, so it survives. G.729 dropped four digits. The failure is exactly the one the theory predicts: G.729 pushed the two tones apart in level until the detector rejected them. Here are five of the digits, with their level difference before and after.
digit level gap before after G.729 detector
3 +1.9 dB +6.3 dB rejected
6 +2.6 dB +6.6 dB rejected
B +2.7 dB +5.4 dB rejected
2 +1.4 dB -0.4 dB kept
Opus, the codec most internet calls use, was not a simple pass or fail. At a normal bitrate it carried every digit. At a low bitrate, or with short tones, it started losing them:
tone length Opus 6 kbit/s Opus 12 kbit/s
100 ms 16 / 16 16 / 16
60 ms 9 / 16 16 / 16
45 ms 5 / 16 11 / 16
The lesson sits in that table. Sending key presses as audio is fragile the moment any real compression is involved.
So the digit travels beside the audio, not inside it#
The fix, from 2006 and still in use, is to stop sending the sound. Instead the sender sends a small packet that says: event 5, still down, for this long. The standard is RFC 4733, and these packets ride the same media channel as the voice but as their own kind of data.
One press becomes a short train of packets.
Four things make this robust, and each is a small, clever decision:
- The first packet sets a marker bit, meaning a new key press has begun.
- Every packet for that press carries the same timestamp, the moment the key went down.
- Each packet reports a larger duration. So any single packet that arrives tells the receiver when the key started and how long it has been held. Lose some in the middle and nothing breaks.
- The final packet, the one that says the key is up, is sent three times, because losing it would leave the key stuck down.
I captured a real one off the wire to check the theory against practice:
marker seq timestamp event end duration
yes 7984 13280 1 no 0
no 7985 13280 1 no 320
no 7986 13280 1 no 640
...
no 7991 13280 1 yes 2240
no 7991 13280 1 yes 2240
no 7991 13280 1 yes 2240
The marker on the first packet, one fixed timestamp, duration climbing by 320 units (40 ms each), and the end packet three times. Exactly the design. It also shows a bug: those three end packets reuse one sequence number, which the standard says they must not. Old test data, breaking a rule that new receivers rely on. That is telephony in one line.
How this bites people in the real world#
Once a key press can travel as sound or as a side packet, the two ends have to agree on which. When they do not, you get the classic faults:
- Every digit arrives twice. Both the tone and the side packet reach the far end, and it counts both. “12” becomes “1122”.
- No digits at all, but the audio is fine. The two ends never agreed to use the side-packet method, so the presses go nowhere.
- Digits vanish after the call is bridged. Somewhere the audio got recompressed through G.729, and the tones did not survive, as in the test above.
- The IVR misses fast presses. The tone was shorter than the detector needs. The old specs say accept above 40 ms and reject below 20 ms, and a fast auto-dialer can sit right on that edge.
A few facts worth keeping:
- A web browser can send DTMF, but it cannot receive it. There is no standard way for page code to be told a key was pressed. If you build a phone menu in the browser, the detecting happens on the server.
- Twilio’s digit collector reads only the side-packet method. Raw tones in the audio are passed through and ignored.
- The SIP INFO method, a third way that sends the digit in the call’s signalling instead of its media, was never standardised. Every system that speaks it does so by imitation, not spec.
Why your card number is a security problem#
The tones are trivial to read. A short bit of code turns them back into digits, and a trained ear can do it too. So when you type your card number during a recorded call, the recording holds your card number, as sound.
The payment-card standard treats this directly. A compliant setup must mask the tones before they are stored, usually by replacing them with a flat tone. There is even a named failure for doing it late: “DTMF bleed”, where the first fraction of each tone leaks through before the masker reacts, which is the same detector delay from earlier turned into a compliance bug.
From a bell to a packet#
A key press started as two tones chosen to dodge the shape of a human voice, read by a filter cheap enough for 1970s hardware. Compression broke the tones, so we stopped sending them and send a small note beside the audio instead. The same “press 1 for billing” now rides as a packet that says which key and for how long, three times at the end so it never gets stuck.
Next time a menu misses your key press, you will have a good guess why. The tone was too short, or it got compressed on the way, or the two ends never agreed on how to send it at all.
The figures here are generated from the real signals, not drawn. The codec and packet numbers are from tests run in a container on Linux.