Voice Conferencing Using a Multicasting Technique

Environment: Visual C++ 6.0, Windows 98/XP

Application Details

This application uses a multicasting technique for audio conferening. Interested clients will join the multicast group address (224.0.0.0 – 239.255.255.255). On the LAN, when any client sends the voice data to the multicast address, it will be delivered to all the clients joined to that group by the underlying network automatically—even the sending host also receives the copy if it has joined to that address and the application has to handle this situation. If the client only wants to send the data and doesn’t want to receive the data, it doesn’t need to join to that group.

On the Internet, this feature is possible if routers support multicasting. Otherwise, virtual multicasting has to be simulated using mtunneling. (Refer to details on MBONE-multicast BACKBONE.)

The client can select the destination user from the user combo box.The s/w also provides save and play features (the user can save the sound the sound and play it later). The client also has a volume control feature. When the client application is started, a microphone select option (recording) is enabled and the microphone mute option is checked (playing) automatically by the program. (The user doesn’t have to worry about the external settings.)

Technical Details

In Display Class

When the client application starts recording and playing threads created in OnInitDialog() of the Display class.

// Create and Start Recorder Thread
record=new RecordSound(this);
record->CreateThread();

//Create and Start Player Thread
play=new PlaySound1(this);
play->CreateThread();

The thread functions are based on the code by the great person Paul Cheffers, from the CodeGuru site). I am greatful to him for making my dream project a reality.

PreCreateHeader() of the Display class (from the constructor) creates some buffers for playing wavedata. (This prevents the creation of buffers during runtime…) When the client presses the connect buttonOnConnect() of the Display class, it connects the client to the server and displays the userlist and start buttons. On pressing the start button, recording and playing are started by sending a message to the recording and playing thread (OnStart function).

record->PostThreadMessage(WM_RECORDSOUND_STARTRECORDING,0,0);
play  ->PostThreadMessage(WM_PLAYSOUND_STARTPLAYING,0,0);

These messages will activate corresponding functions defined in the messagge map of the respective thread class.

On pressing the stop button, recording and playing are stopped in the same way as above (OnStop Function). It also contains other functions that will be activated on pressing the buttons….and some functions are activated from other classes. (mysocket and RecordSound classes).

Mysocket Class

Before starting the application, the client has to join the multicat group by using the mulitcast group address and port. This has been done in the CreateSocket(…) function (called from the Display class). To receive the message, the client has to join the multicast group. The steps do accomplish this are as follows.

  1. Create receiver socket:
  2. Create(gport,SOCK_DGRAM, FD_READ)
  3. Allow other applications to use the port (gport).
  4. SetSockOpt(SO_REUSEADDR, (void*)&bMultipleApp
               sizeof(BOOL), SOL_SOCKET);
    
  5. Join to the multicast group:
  6. ip_mreq mreq;
    mreq.imr_multiaddr.s_addr = inet_addr(gaddr);  //group address
    mreq.imr_interface.s_addr = htons(INADDR_ANY);
    
    setsockopt(m_hSocket,IPPROTO_IP, IP_ADD_MEMBERSHIP,
               (char FAR *)&mreq,sizeof(mreq));
    

To send the data, the steps are as follows:

  1. Create Sending socket:
  2.     SOCKADDR_IN hgroup;
        CAsyncSocket send;
        memset(&hgroup, 0, sizeof(hgroup));
        hgroup.sin_family      = AF_INET;
        hgroup.sin_addr.s_addr = inet_addr(gaddr);
        hgroup.sin_port        = htons((USHORT)gport);
    
        send.Create(0, SOCK_DGRAM, 0);
    
  3. Set TTL value…important:
    ttl=8;    //some value > 1
    
    send.SetSockOpt(IP_MULTICAST_TTL, &ttl, sizeof(int),
                    IPPROTO_IP)
    
  4. Set loopback option to false to prevent loopback (optional).
  5.     //depends upon underlying protocol...
        //application has to handle loopback(prefered...)
    

RecordSound Class

The PreCreateHeader() function creates buffers for recording data.These are added using the waveInPrepareHeader() and waveInAddBuffer() functions in the OnStartRecording function. (This function is called when the Start button is clicked, as explained earlier.)

Playsound1 Class

Contains the functions for starting, playing, and stopping wavedata. Buffers are created initially in Display class itself.

MicMute, MicPhone, and Mixer are the special classes to add several extra features to the Voice – Chat function. Some of the concepts are collected from various developers on the CodeGuru site. I am greatful to those developers!!!

Running the Application

LAN: To start the application, run the client program and specify the multicast group address (224.2.0.0 … 239.255.255.255) and port (Specify an even number > 1024) and type the username. Then, press the Connect button to connect to the group. If you are successfully connected to the group, the start button will be displayed. On clicking the start button, recording will be started. Playing will be started automatically when new data arrives.

On the Internet, a virtual environment has to be provided by using mtunneling because most routers don’t support multicasting.

Note: Any clients can send the data at any time. Performance depends upon the situation. Developers are free to use their own ideas to improve. (Please let me know if you see some new mechanism.)

I am eagarly waiting for your doubts and suggestions at nsry2002@yahoo.co.in.

I am greatful to the CodeGuru site for connecting developers….and helping to realise their dreams!!!

Downloads

Download source – 130 Kb

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read