Home>

Voice capture

To send a voice message,First get the voice,There are several ways here,One is to use directx's directxsound to record. For the sake of simplicity, I use an open source plug-in naudio for voice recording. Reference naudio.dll in the project

//------------------ 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 (invokerequired)
      {
        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 ();
    }

The above code implements recording,And write to the file p2psound_a.wav

Voice transmission

After getting the voice, we need to send it out

When we recorded the sound and clicked Send,The relevant code for this part is

msgtranslator tran=null;
ublic form1 ()
    {
      initializecomponent ();
      loadwasapidevicescombo ();//Show audio devices
      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 the 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, fileaccess.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 the resource
          fs.close ();
        }
      }
    }

In this way, we will send the generated voice file.

Reception and playback of voice

In fact, the reception of voice is not the same as the reception of text messages.It ’s just that the voice is sent in binary,So after receiving the voice, we should write it into a file,After receiving,Just play this voice.

The following code is mainly to save the received data to a file.This functional event is triggered when a message is received in my netframe,In the article mentioned earlier

void tran_messagereceived (object sender, messageeventargs e)
    {
      msg msg=e.msg;
      if (msg.type == consts.message_binary)
      {
        string m=msg.type + "->" + msg.username + "Send a 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);
      }
    }

After receiving the voice message,We want to play,When playing, still use the plug-in just now

//-------- 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 () {singlereaderobject=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);
    }

Shown above is the interface to receive and send a voice message

Technical summary

The main technology used is the recording and playback functions of udp and naudio

c
  • Previous Detailed usage case of TelephonyManager class in Android
  • Next Use regular expression NSRegularExpression in iOS to validate textfiled input