PJSIP and RingCentral — Part 3: DTMF

Tyler Long
Mar 10, 2020 · 5 min read
Customer answering recorded phone call survey sent to them!!!

Welcome to Part 3 of the PJSIP and RingCentral article series. In Part 1 we introduced PJSIP to you and we also showed you a simple demo on how you use PJSIP for making phone calls through RingCentral. In Part 2 we focused on medias, we talked about both using a media player and recorder, we also provided code snippets to use wav files in a phone call. In this part, we will cover a new topic: DTMF.

For this article I’d like to divide it into 3 sub-topics:

  1. What is DTMF and what is it used for?
  2. How to handle DTMF with PJSIP?
  3. A PJSIP DTMF demo: telephony survey

What is DTMF and what is it used for?

DTMF is required if you want to do an “automatic interactive phone call”. Let’s say you want to conduct a telephone survey to 1000 targeted users. The survey content doesn’t matter here, let’s say it’s about one’s favorite color:

You definitely don’t want to do it manually, because making 1000 phone calls is too time-consuming. So let’s do it automatically by using PJSIP. This helps make it very simple to ask users questions — you just pre-record the questions and play them during the phone call. But how do the users answer those questions? The solution is DTMF. Users can press a number on the keypad to answer the questions.

DFMF has a lot of other use cases, for example, with DTMF you could even remotely control a vehicle via a phone call (1 for going forward; 2 for going backward; 3 for turning left; 4 for turning right…etc). In this article, we will only focus on doing “automatic interactive phone calls”, like the favorite color survey we mentioned above.

How to handle DTMF with PJSIP?

To Receive DTMF inputs from a remote peer, you just subclass the Call class, and override the onDtmfDigit callback method. Whenever the remote peer presses a digit, onDtmfDigit will be invoked:

To send DTMF signals to a remote peer, you simply call this method of the Call class:

void dialDtmf(const string &digits)

OK, now we know enough about DTMF and how to use DTMF with PJSIP, so it’s time to build a demo!

A PJSIP DTMF demo: telephony survey

We are going to implement the telephony survey demo we talked about before.

First we need to pre-record some audio that we can play to the callees. We need 7 audio files in order to save time, I created a script to generate them in batch:

say -o greetings_temp.wav --data-format=LEI16@48000 "Welcome to the telephony survey demo" && ffmpeg -i greetings_temp.wav audios/greetings.wav && rm greetings_temp.wavsay -o question_temp.wav --data-format=LEI16@48000 "Which color do you like? 1 for red, 2 for green, 3 for blue" && ffmpeg -i question_temp.wav audios/question.wav && rm question_temp.wavsay -o invalid_temp.wav --data-format=LEI16@48000 "Invalid option" && ffmpeg -i invalid_temp.wav audios/invalid.wav && rm invalid_temp.wavsay -o red_temp.wav --data-format=LEI16@48000 "You like red" && ffmpeg -i red_temp.wav audios/red.wav && rm red_temp.wavsay -o green_temp.wav --data-format=LEI16@48000 "You like green" && ffmpeg -i green_temp.wav audios/green.wav && rm green_temp.wavsay -o blue_temp.wav --data-format=LEI16@48000 "You like blue" && ffmpeg -i blue_temp.wav audios/blue.wav && rm blue_temp.wavsay -o bye_temp.wav --data-format=LEI16@48000 "The demo is over, the call will be hang up in 3 seconds, bye" && ffmpeg -i bye_temp.wav audios/bye.wav && rm bye_temp.wav

The command above only works on macOS. For other operating systems, please use other tools to generate audio files. Now we should have 7 audio files: greetings.wav, question.wav, invalid.wav, red.wav, green.wav, blue.wav, bye.wav .

Let’s create 7 players for them:

// declaration
GreetingsAudioMediaPlayer greetingsPlayer;
QuestionAudioMediaPlayer questionPlayer;RedAudioMediaPlayer redPlayer;GreenAudioMediaPlayer greenPlayer;BlueAudioMediaPlayer bluePlayer;InvalidAudioMediaPlayer invalidPlayer;ByeAudioMediaPlayer byePlayer;
// create playersinvalidPlayer.createPlayer("demos/survey/audios/invalid.wav");questionPlayer.createPlayer("demos/survey/audios/question.wav");byePlayer.createPlayer("demos/survey/audios/bye.wav");greetingsPlayer.createPlayer("demos/survey/audios/greetings.wav");redPlayer.createPlayer("demos/survey/audios/red.wav");greenPlayer.createPlayer("demos/survey/audios/green.wav");bluePlayer.createPlayer("demos/survey/audios/blue.wav");

Make a phone call to the callee:

call = new MyCall(*myAccount);CallOpParam prm(true); // Use default call settingscall->makeCall("sip:" + calleeNumber, prm);

Once the phone call is answered, we play the greetings audio:


Once the greetings audio reaches Eof, we play the questions audio:

bool GreetingsAudioMediaPlayer::onEof(){this->stopTransmit(*audioMedia);questionPlayer.startTransmit(*audioMedia);questionPlaying = true;return false;}

Then we listen for the DTMF input from remote peer, and take actions accordingly:

If a user selected an invalid option, we will play the invalid audio file and play question audio again to ask for input:

bool InvalidAudioMediaPlayer::onEof(){this->stopTransmit(*audioMedia);questionPlayer.setPos(0);questionPlayer.startTransmit(*audioMedia);return true;}

If user selected a valid option, we play the confirmation audio followed by the bye audio. Once the bye audio reaches Eof , we hang up the call:

bool ByeAudioMediaPlayer::onEof(){this->stopTransmit(*audioMedia);CallOpParam callOpParam;call->hangup(callOpParam);return false;}

That is the main logic and important code snippets for the favorite color survey demo. If you want a ready to run project, please refer to the source code here.


In this article, we learned a new PJSIP topic: DTMF. DTMF is often used to gather input from remote peer of a phone call. It is easy to manipulate DTMF with PJSIP. We’ve gone through the details of a real demo and it should be a good reference for you to be able to create your own DTMF project.

To learn even more about other features we have make sure to visit our developer site and if you’re ever stuck make sure to go to our developer forum.

Want to stay up to date and in the know about new APIs and features? Join our Game Changer Program and earn great rewards for building your skills and learning more about RingCentral!

RingCentral Developers

Cloud Business Communications