DirectX programming: Using Sockets in C # to implement network voice communication [Primary version]__ programming

Source: Internet
Author: User

[Statement: This article source: http://www.cnblogs.com/stg609/archive/2008/11/19/1334544.html Author: stg609]

Nowadays, there are many VoIP software, more famous is Skype, there are other such as Uucall, shutter and so on. They provide the function in addition to voice calls on the network, but also with the fixed phone, cell phone and other calls. In this article, we mainly introduce the basic method of using C # to realize voice communication. But at present only realized the basic function of voice transmission on the network, and relatively rough, did not use what algorithm to optimize, so we must not expect too much. I am writing this article in addition to recording their own experience, I would like to have experts to give improved ideas or algorithms.

Development platform:. NET Framework 2.0, VS 2005,windows xp,directx SDK (June 2008) download page.
Development language: C #.

Test environment: Windows XP,. NET Framework 2.0, general LAN.
Test results: In multiple installations of Windows XP system and configuration of different computers on the test, can be normal operation. Voice conversations can be made, but there is an obvious murmur, along the low.

Limited to space, in this article will be introduced in detail I think the crux of the problem, the other part only to do a general introduction, in order to facilitate understanding, you can first read:
1.DirectX programming: [Use DirectSound recording in primary]c#
2.c# Socket Programming Notes

In this article, you intend to introduce the following sequence:
1. Project Results Preview and description
2. Summary of Implementation methods
3. Language acquisition
4. Voice transmission
5. Voice Playback

Project Results Preview and description

The interface is as follows:

Description: The interface is very simple, only to provide a choice or input the other IP function, when the appropriate LAN IP selection, click OK to activate the Voice chat button. If you want to do voice chat can start chatting, chat port using 8000. The software is only applicable to users in the LAN chat, in addition, because there is no increase in user authentication function, so only the two sides have launched the software to be able to communicate. If you only want to test on a single computer, you only need to select the IP of this machine. Because of the technical level, try n times, do not know how to correctly achieve the voice effect (such as echo cancellation, noise reduction, etc.) to protect the sound quality, so in a single test will have echo interference, shouting more serious, hope Master creators.

Overview of Implementation methods

There are a few steps you can take to achieve voice chat (that is, I don't say, believe you should be able to get some):
A voice capture: the function of acquisition is to get data from your microphone, I use the DirectSound class to implement this technology. Reference: Using DirectSound Recordings in C #
(b) Speech coding: The speech coding algorithm is used to compress and encode the collected speech, and the purpose of encoding is to reduce the pressure of network bandwidth. )
C Voice Transmission: The collected sound transmission to other hosts on the network, I use the socket UDP method to achieve. Reference: C # Socket Programming notes
(d Speech Decoding: If the transmitted speech is compressed, the speech must be decoded, otherwise the original speech data cannot be obtained.) )
E Voice Playback: When the other side over the network transmission to the machine (, if you need to decode the first execution D), for real-time playback.

The red marked steps above can be omitted. In this software, I did not take these two steps, because when I took these two steps, I found that the speech delay is abnormally serious. I used the codec algorithm is g.729, the use of the G729.dll library files, compression effect is good, but the delay is more serious, it may be their own where not set up good. If a friend has used the algorithm, and the delay is low, I hope the generous enlighten.

Next, focus on speech collection, voice transmission, voice playback implementation.

Voice Capture
Because the method is implemented in line with the recording method, so it will not be too much, if you do not understand well, please refer to: C # using DirectSound recording

Unlike the recording, we need to create a wave file to store the collected data, while in voice chat, there is no need to store, when some data is collected, immediately sent out, so there is no need to open up a lot of space to store PCM data.
Let's take a look at the basic steps of the acquisition:
1. Set the PCM format, set the relevant parameters, such as: sampling frequency, the number of digits, such as quantization.
2. Set up a collection of equipment objects, set up a collection of buffer objects.
3. Set the buffer notification to set the event after the notification is triggered. A notification is used to trigger a notification event when the read pointer to a buffer reaches a preset position, reminding us that a portion of the data can be transmitted.
4. Start collecting sound.
5. When the notification is triggered, a new thread is created to handle the data transfer event. (A new thread is created to prevent the capture process from being interrupted).
<summary>
Set audio formats, such as sample rate, etc.
</summary>
<returns> formatting after completion </returns>
Private Waveformat Setwaveformat ()
{
Waveformat format = new Waveformat ();
Format. Formattag = waveformattag.pcm;//Set Audio type
Format. Samplespersecond = 11025;//Sample rate (in Hertz) typical value: 11025, 22050, 44100Hz
Format. BitsPerSample = 16;//number of sampled digits
Format. Channels = 1;//Channel
Format. Blockalign = (short) (format. Channels * (format. BITSPERSAMPLE/8);//number of bytes per unit sampling point
Format. Averagebytespersecond = format. Blockalign * format. Samplespersecond;

return format;
According to the above sampling specifications, the number of bytes sampled for 1 seconds is 22050*2=44100b about 43K.
}

<summary>
To create a capture device object
</summary>
<returns> If the creation succeeds in returning true</returns>
private bool Createcaputerdevice ()
{
The first thing to do is to raise the available capture device
Capturedevicescollection Capturedev = new Capturedevicescollection ();
Guid Devguid;
if (Capturedev. Count > 0)
{
Devguid = capturedev[0]. Driverguid;
}
Else
{
System.Windows.Forms.MessageBox.Show ("Currently there is no device available for audio capture", "System hints");
return false;
}
Using the device GUID to create a capture device object
Capture = new Capture (DEVGUID);
return true;
}

<summary>
To create a capture buffer object
</summary>
private void Createcapturebuffer ()
{
To create a capture buffer, you must have two parameters: buffer information (describing the format in this buffer, etc.), buffering device.
Waveformat Mwavformat = Setwaveformat ();
Capturebufferdescription bufferdescription = new Capturebufferdescription ();
BufferDescription. Format = mwavformat;//Set the data formats to be captured by the buffer
Inotifysize = mwavformat.averagebytespersecond/inotifynum;//1 seconds of data volume/set of notification number per notification size less than 0.2s of data volume, voice latency less than 200ms for high-quality voice
Ibuffersize = Inotifynum * inotifysize;
BufferDescription. Bufferbytes = ibuffersize;
BufferDescription. Controleffects = true;
BufferDescription. Wavemapped = true;
Capturebuffer = new Capturebuffer (bufferdescription, capture);//Set Device Buffer object

}

Setting Up Alerts
private void Createnotification ()
{
bufferpositionnotify[] BPN = new bufferpositionnotify[inotifynum];//Set Number of buffer notifications
Setting up Notification events
Notifyevent = new AutoResetEvent (false);
Notifythread = new Thread (recodata);//Notification Trigger event
Notifythread.isbackground = true;
Notifythread.start ();
for (int i = 0; i < inotifynum; i++)
{
Bpn[i]. Offset = inotifysize + i * inotifysize-1;//set the location of each specific
Bpn[i]. Eventnotifyhandle = Notifyevent.handle;
}
mynotify = new Notify (capturebuffer);
Mynotify.setnotificationpositions (BPN);

}

Events in a thread
private void Recodata ()
{
while (true)
{
Wait for a notification message for the buffer
Notifyevent.waitone (Timeout.infinite, true);
Recording data
Recordcaptureddata (Client,epserver);
}
}

The real data transfer event is actually transferring data to the network.
private void Recordcaptureddata (Socket client,endpoint epserver)
{
byte[] Capturedata = null;
int readpos = 0, Capturepos = 0, locksize = 0;
Capturebuffer. GetCurrentPosition (out of Capturepos, out Readpos);

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.