softphone icon Course 3 / Lecture 2

How to build an IVR with Ozeki VoIP SIP SDK

How to create blind transfer and voice control feature

In the previous example we created a basic IVR system written in C# by using the tools and functions of the Ozeki VoIP SIP SDK. In this program we made a softphone for our IVR and registered it to the PBX. After the registration and the creation of the phone line we made a class to manage the calls. In this class we set that if there is an incoming call, then the user hears a welcome message and he/she able to control the IVR by using DTMF buttons.
If you click on the following link, you can reach the full description of the Basic IVR example code.

Tutorial Part 1 - C# Basic IVR

In this tutorial example we will learn the followings:

  • How to use the Blind transfer function in our IVR system
  • How to create a Voice controlled IVR by using the functions and events of the Speech to Text class

Video Tutorial:

How to develop IVR by using Ozeki VoIP SDK - Tutorial 2

video tutorial

In these example programs you will be able to add numbers to the console application for using the blind transferring functionality and you can control your IVR system by using your voice if you would like to modernize your system with this feature.

For the source code of the Blind transferer IVR, please click here!




For the source code of the Voice controlled IVR, please click here!




We are using three classes in these examples:

  • Softphone.cs
    The softphone's implementation goes here, all of it's events, methods, functions, variables.
  • CallHandler.cs
    This class is for handling the incoming calls of the IVR and managing the IVR menu options.
  • Program.cs
    Our class with the Main() method, this class controls the console window, interacts with the user, by using softphone and callhandler objects.

The implementation of the call transfer functionality

You only need to modify the Program and CallHandler classes of the Basic IVR code. In the Program.cs the user has to add a number to the system which will be the number what he/she would like to reach via the Blind transfer option. After the input request the code needs to pass this value to the CallHandler.cs.


Create a static string type variable called blindTransfer. It is static because you will use this value in more than one methods of the Program class.

static string blindTransfer;

The Main() method

Add two lines to the Main() method. The first is to inform the user that he/she must add a number for the system to use the Blind transferring functionality. If he/she does not want to use this option, then press '0'. The second code line is for reading a value from the user and storeing it in the blindTransfer variable. The Read() function has two parameters: the name of the variable name in string format, the second is a bool. If it is true, then the racall will continue until the input is not null or empty.

Console.WriteLine("Please set the number for blind transferring! If you don't want to use this function of the IVR, press 0!");
blindTransfer = Read("blindTransfer", true);

The softphone_IncomingCall() method

If your variable contains the added number then the system needs to pass this value to the CallHandler class and you can do this by calling a method in the softphone_IncomingCall section of the Program class because there you can find a CallHandler object.


With this you can pass the blindTransfer value to the CallHandler class. But this method doesen't exist yet, so you need to create it in the CallHandler.cs.


There is no need to many modifications in the CallHandler class either. Just add a new string type blindTransferNumber local variable:

string blindTransferNumber;

The BlindTransferNumber()

Now create the BlindTransferNumber method what you called in the Program.cs. The parameter is the value from the Program class and the new blindTransferNumber will be equal with this. So you can work with this value in this class now.

public void BlindTransferNumber(string blindTransfer)
     blindTransferNumber = blindTransfer;

The call_DtmfReceived() method

The only thing left is add a new case to the switch statement in the call_DtmfReceived method and check that if the value of the blindTransferNumber is 0 or anything else. If it 0, then inform the user that he/she can't use the blind transfer function because he/she didn't add any number for it. Else call the BlindTransfer method with the blindTransferNumber value.

void call_DtmfReceived(object sender, VoIPEventArgs<DtmfInfo> e)
            switch (e.Item.Signal.Signal)
                case 0: break;
                case 1: TextToSpeech("Ozeki Informatics Ltd. is a leading mobile messaging software vendor and Ozeki VoIP SIP SDK is an excellent software development kit that allows you to establish VoIP calls from your application easily and quickly. You do not need to have expert programming skills, with the most basic programming knowledge you will be able to create extraordinary VoIP solutions with this tool."); break;
                case 2: MP3ToSpeaker(); break;
                case 3:
                        if (blindTransferNumber == "0")
                            TextToSpeech("You did not add any number for blind transferring!");

Creation of the Voice controlled IVR

In this example we are going to create an IVR, which can be controlled by human speech so it is not needed to press any BTMF buttons to navigate between the IVR menu items. For this you only need to modify the CallHandler class of the basic IVR source code and implement the events and methods of the SpeechToText abstract class.


We will manage the incoming calls for the IVR here, just like we did in the Basic IVR and Blind transfer IVR example codes.


You should create some new objects: a PhoneCallAudioReceiver for receiving audio from the caller, an IEnumerable for giving word options to the system to recognize them and a SpeechToText to convert the human speech into text format.

PhoneCallAudioReceiver phoneCallAudioReceiver;
IEnumerable<string> choices;
SpeechToText stt;

The CallHandler() constructor

In this section you need to set the created object and make instances for them. The PhoneCallAudioReceiver needs to be atttached to the call, and you need to create an instance for the SpeechToText via the CreateInstance method of the SpeechToText class. You also need to add some words to the choices list what will help to the system recognize words.

public CallHandler(ICall call)
      greetingMessageTimer = new Timer();
      greetingMessageTimer.Interval = 30000;
      greetingMessageTimer.Elapsed += greetingMessageTimer_Elapsed;
      this.call = call;
      phoneCallAudioSender = new PhoneCallAudioSender();
      mediaConnector = new MediaConnector();
      phoneCallAudioReceiver = new PhoneCallAudioReceiver();
      choices = new List<string>() { "first", "second"};
      stt = SpeechToText.CreateInstance(choices);

The Start() method

In the Start() method you need to connect the PhoneCallAudioReceiver to the stt with the help of the mediaConnector. This is for giving the human speech to the recognizing section. And you have to subscribe on the WordHypothesized event of the SpeechToText class.

public void Start()
     mediaConnector.Connect(phoneCallAudioReceiver, stt);
     call.CallStateChanged += call_CallStateChanged;
     stt.WordHypothesized += CallHandler_WordHypothesized;

The CallHandler_WordHypothesized() method

If the system detects the user speaking and the reconized word fits one the words in the choices list, then it starts the CallHandler_WordHypothesized() method which handles the the switch statement. If the user says "first", he/she can hear some information about the Ozeki Ltd. and the Ozeki VoIP SDK. By saying "second" , he/she can hear a sample mp3 song.

void CallHandler_WordHypothesized(object sender, SpeechDetectionEventArgs e)
      switch (e.Word.ToString())
           case "first": TextToSpeech("Ozeki Informatics Ltd. is a leading mobile messaging software vendor. It offers easy-to-use and feature-rich telcommunication products for businesses and organizations."); break;
           case "second": MP3ToSpeaker(); break;


As you can see, with the help of these examples, you can create and modernize your IVR system by using Ozeki VoIP SIP SDK. Now you are able to use the Blind Transfer method and the components of the SpeechToText class if you would like to control your IVR system via human speech.

The next example will introduce how to:

  • Create a Multi-Level IVR system

Tutorial Part 3 - Multi-level IVR

Related Pages

More information