Declaration of originalityThe source of this post is http://blog.csdn.net/zhujunxxxxx/article/details/40124773 if reproduced please indicate the source. This article author original, email [email protected], if you have any questions, please contact the author Overview
Previously sent an article http://blog.csdn.net/zhujunxxxxx/article/details/38864817 has implemented the UDP sub-packet to send the data function, This article is primarily an application that uses UDP to transmit information such as voice and text.
Voice Acquisition
To send voice messages, first get voice, here are a few ways, one is to use DirectX sound to record, I use a simple open source plugin naudio to achieve voice admission. Referencing NAudio.dll in a project
<span style= "FONT-SIZE:14PX;" >//------------------Recording related-----------------------------private Iwavein WaveIn; Private Wavefilewriter writer; private void Loadwasapidevicescombo () {var deviceenum = new Mmdeviceenumerator (); var devices = deviceenum.enumerateaudioendpoints (Dataflow.capture, devicestate.active). ToList (); Combobox1.datasource = devices; Combobox1.displaymember = "FriendlyName"; } private void Createwaveindevice () {WaveIn = new WaveIn (); Wavein.waveformat = new Waveformat (8000, 1); Wavein.dataavailable + = ondataavailable; wavein.recordingstopped + = onrecordingstopped; } void ondataavailable (object sender, Waveineventargs e) {if (this. invokerequired) {this. BeginInvoke (New eventhandler<waveineventargs> (ondataavailable), sender, E); } else {writer. Write (e.buffer, 0, e.bytesrecorded); int secondsrecorded = (int) (writer. Length/writer. Waveformat.averagebytespersecond); if (secondsrecorded >= 10)//maximum 10s {Stoprecord (); } else {L_sound. Text = secondsrecorded + "s"; }}} void Onrecordingstopped (object sender, Stoppedeventargs e) {if (invokere quired) {BeginInvoke (new eventhandler<stoppedeventargs> (onrecordingstopped), sender, E); } else {finalizewavefile (); }} void Stoprecord () {allchangebtn (Btn_luyin, true); Allchangebtn (Btn_stop, false); ALLCHANGEBTN (Btn_sendsound, true); ALLCHANGEBTN (Btn_play, true); Btn_luyin. Enabled = true; Btn_stop.enabled = false; Btn_sendsound. Enabled = true; Btn_play. Enabled = true; if (WaveIn! = null) wavein.stoprecording (); Cleanup (); }private void Cleanup () {if (WaveIn! = null) {wavein.dispose (); WaveIn = null; } finalizewavefile (); private void Finalizewavefile () {if (writer! = null) {writer. Dispose (); writer = null; }}//Start recording private void Btn_luyin_click (object sender, EventArgs e) {btn_stop. Enabled = true; Btn_luyin. Enabled = false; if (WaveIn = = null) {Createwaveindevice (); } if (File.exists (soundfile)) {file.delete (soundfile); } writer = new Wavefilewriter (soundfile, Wavein.waveformat); Wavein.startrecording (); }</span>
The above code implements the recording and writes the file P2psound_a.wav
Voice Send
We're going to send the voice out after we get the voice.
When we record the sound and click Send, this part of the relevant code is
<span style= "FONT-SIZE:14PX;" > Msgtranslator tran = null; Public Form1 () {InitializeComponent (); Loadwasapidevicescombo ();//display audio device Config cfg = Seiclient.getdefaultconfig (); Cfg. Port = 7777; Udpthread UDP = new Udpthread (CFG); Tran = new Msgtranslator (UDP, CFG); Tran. Messagereceived + = tran_messagereceived; Tran. Debuged + = new eventhandler<debugeventargs> (tran_debuged); }private void Btn_sendsound_click (object sender, EventArgs e) {if (t_ip. Text = = "") {MessageBox.Show ("Please enter IP"); Return } if (T_port. Text = = "") {MessageBox.Show ("Please enter port number"); Return } String IP = t_ip. Text; int port = Int. Parse (T_port. Text); String Nick = T_nick. Text; String msg = "Voice message"; IPEndPoint remote = new IpendpoinT (Ipaddress.parse (IP), port); msg m = new msg (remote, "ZZ", Nick, Commands.sendmsg, MSG, "Come from A"); M.isrequirereceive = true; M.extendmessagebytes = Filecontent (soundfile); M.packageno = Msg.getrandomnumber (); M.type = consts.message_binary; Tran. Send (m); }private byte[] Filecontent (string filename) {FileStream fs = new FileStream (FileName, FileMode.Open, F Ileaccess.read); try {byte[] Buffur = new Byte[fs. Length]; Fs. Read (Buffur, 0, (int) fs. Length); return Buffur; } catch (Exception ex) {return null; } finally {if (fs! = NULL) {//close resource Fs. Close (); }}}</span>
So we send out the resulting voice file.
reception and playback of voice
In fact, the reception of voice and text messages are not different, except that the voice is sent in binary, so we should write to a file after receiving the voice, the reception is completed, play this voice on the line.
The following code is mainly to save the received data to the file, the function of my netframe received the message triggered by the event, in the article mentioned earlier in the article
<span style= "FONT-SIZE:14PX;" >void tran_messagereceived (object sender, Messageeventargs e) {Msg msg = e.msg; if (Msg. Type = = consts.message_binary) {string m = Msg. Type + "-+" + MSG. UserName + "Send binary message!"; Addservermessage (m); if (file.exists (Recive_soundfile)) {file.delete (recive_soundfile); } FileStream fs = new FileStream (Recive_soundfile, FileMode.Create, FileAccess.Write); Fs. Write (Msg. Extendmessagebytes, 0, Msg. Extendmessagebytes.length); Fs. Close (); Play_sound (Recive_soundfile); CHANGEBTN (TRUE); } else {string m = Msg. Type + "-+" + MSG. UserName + "say:" + MSG. normalmsg; Addservermessage (m); }}</span>
After receiving the voice message, we want to play, and still play with the plugin that was just played
<span style= "FONT-SIZE:14PX;" >//--------Play part----------private Iwaveplayer waveplayer; Private WaveStream reader; public void Play_sound (string filename) {if (Waveplayer! = null) {Waveplayer . Dispose (); Waveplayer = null; } if (reader! = null) {reader. Dispose (); reader = new Mediafoundationreader (filename, new mediafoundationreader.mediafoundationreadersettings () {Sing Lereaderobject = true}); if (Waveplayer = = null) {Waveplayer = new waveout (); waveplayer.playbackstopped + = waveplayeronplaybackstopped; Waveplayer.init (reader); } waveplayer.play (); } private void Waveplayeronplaybackstopped (object sender, Stoppedeventargs Stoppedeventargs) {if (stoppedeventargs.exception! = null) { MessageBox.Show (StoppedEventArgs.Exception.Message); } if (Waveplayer! = null) {waveplayer.stop (); } btn_luyin. Enabled = true; }private void Btn_play_click (object sender, EventArgs e) {Btn_luyin. Enabled = false; Play_sound (Soundfile); }</span>
The interface for receiving and sending a voice message is shown above
Technical Summary
The main technology used is the recording and playback functions of UDP and Naudio.
The UDP transport class used in it I put it on GitHub. Address in the personal profile on the left side of my blog address item address Https://github.com/zhujunxxxxx/ZZNetFrame
I hope this article can provide a way of thinking.
C # Speech-to-peer voice chat tool based on UDP implementation