How to make an outbound conference call - with example code

This article is about to introduce how to create a softphone which is able to handle multiple outgoing calls, and connect them together. To fully understand this guide, you might need to study the How to Make SIP voice call article first.

client mixed conference call
Figure 1 - Client mixed conference calls

What is client mixed conference call?

Conference calling is a basic requirement for VoIP systems. This is because the spread of voice over IP technology increased the wish for digitizing more advanced communication forms like lectures or conferences.

Conference calls are basically made by using client mixing meaning that all the clients can hear anything any of the other clients tells (Figure 1).

How to implement conference call using C#?

The audio conferencing is supported by a special tool in the Ozeki VoIP SIP SDK called ConferenceRoom. It is a MediaHandler that makes all the background work and you only need to add the calls to it - and remove them, when needed.

All you have to do is to create a ConferenceRoom instance, and call its StartConferencing() method after the phone line has been successfully registered. Since now you have a conference room, when an outgoing call occurs and that enters into Answered call state, you have to add the call to the conference room with the AddToConference() method, and if a call ends, you have to remove that with the RemoveFromConference() method.

Client mixed conference call in C#

using System;
using Ozeki.Media;
using Ozeki.VoIP;
using System.Threading;

namespace Conference_Call
{
    class Program
    {
        static ISoftPhone _softphone;   // softphone object
        static IPhoneLine _phoneLine;   // phoneline object
        static IPhoneCall _call;
        static Microphone _microphone;
        static Speaker _speaker;


        static ConferenceRoom _conferenceRoom;
        private static WaveStreamRecorder _recorder;

        private static void Main(string[] args)
        {
            _microphone = Microphone.GetDefaultDevice();
            _speaker = Speaker.GetDefaultDevice();


            // Create a softphone object with RTP port range 5000-10000
            var userAgent = "Conference-example";
            _softphone = SoftPhoneFactory.CreateSoftPhone(5000, 10000, userAgent);

            // SIP account registration data, (supplied by your VoIP service provider)
            var registrationRequired = true;
            var userName = "100";
            var displayName = "100";
            var authenticationId = "100";
            var registerPassword = "100";
            var domainHost = "192.168.0.126";
            var domainPort = 5060;

            var account = new SIPAccount(registrationRequired, displayName, userName, authenticationId, registerPassword, domainHost, domainPort);

            // Send SIP regitration request
            RegisterAccount(account);

            // Prevents the termination of the application
            Console.ReadLine();
        }

        static void RegisterAccount(SIPAccount account)
        {
            try
            {
                _phoneLine = _softphone.CreatePhoneLine(account);
                _phoneLine.RegistrationStateChanged += line_RegStateChanged;
                _softphone.IncomingCall += softphone_IncomingCall;
                _softphone.RegisterPhoneLine(_phoneLine);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error during SIP registration: " + ex);
            }
        }

        static void InitializeConferenceRoom()
        {
            _conferenceRoom = new ConferenceRoom();
            _conferenceRoom.StartConferencing();
        }

        static void softphone_IncomingCall(object sender, VoIPEventArgs e)
        {
            IPhoneCall call = e.Item;
            call.CallStateChanged += call_CallStateChanged;
            call.Answer();
        }

        private static void CreateCall()
        {
            var numberToDial = "116";
            _call = _softphone.CreateCallObject(_phoneLine, numberToDial);
            _call.CallStateChanged += call_CallStateChanged;
            _call.Start();
        }

        private static void CreateCall2()
        {
            var numberToDial = "126";
            _call = _softphone.CreateCallObject(_phoneLine, numberToDial);
            _call.CallStateChanged += call_CallStateChanged;
            _call.Start();
        }

        private static void SetupDevices(IPhoneCall call)
        {
            _conferenceRoom.ConnectReceiver(_speaker);
            _conferenceRoom.ConnectSender(_microphone);

            //Uncomment to record the sounds of the conference room
            //_recorder = new WaveStreamRecorder("hello.wav");
            //_conferenceRoom.ConnectReceiver(_recorder);
            //_recorder.Start();

            _speaker.Start();
            _microphone.Start();
        }

        static void line_RegStateChanged(object sender, RegistrationStateChangedArgs e)
        {
            if (e.State == RegState.NotRegistered || e.State == RegState.Error)
                Console.WriteLine("Registration failed!");

            if (e.State == RegState.RegistrationSucceeded)
            {
                Console.WriteLine("Registration succeeded - Online!");
                InitializeConferenceRoom();
                CreateCall();

                Thread.Sleep(10000);

                CreateCall2();
            }
        }

        static void call_CallStateChanged(object sender, CallStateChangedArgs e)
        {
            IPhoneCall call = sender as IPhoneCall;

            if (e.State == CallState.Answered)
            {
                _conferenceRoom.AddToConference(call);
                SetupDevices(call);
            }
            else if (e.State.IsCallEnded())
            {
                _conferenceRoom.RemoveFromConference(call);
                call.CallStateChanged -= call_CallStateChanged;
                StopDevices(call);
            }
            else if (e.State == CallState.Completed)
            {
                _conferenceRoom.RemoveFromConference(call);
                call.CallStateChanged -= call_CallStateChanged;
                StopDevices(call);

            }
        }

        private static void StopDevices(IPhoneCall call)
        {
            _conferenceRoom.DisconnectReceiver(_speaker);
            _conferenceRoom.DisconnectSender(_microphone);

            //_conferenceRoom.DisconnectReceiver(_recorder);
            //_recorder.Stop();
            //_recorder.Dispose();

            _speaker.Stop();
            _microphone.Stop();
        }
    }
}

Related Pages