directsound录音

private  void  RecordCapturedData(Socket Client,EndPoint epServer )
         {
             byte [] capturedata =  null ;
             int  readpos = 0, capturepos = 0, locksize = 0;
             capturebuffer.GetCurrentPosition( out  capturepos,  out  readpos);
             locksize = readpos - iBufferOffset; //这个大小就是我们可以安全读取的大小
             if  (locksize == 0)
             {
                 return ;
             }
             if  (locksize < 0)
             { //因为我们是循环的使用缓冲区,所以有一种情况下为负:当文以载读指针回到第一个通知点,而Ibuffeoffset还在最后一个通知处
                 locksize += iBufferSize;
             }
             capturedata = ( byte [])capturebuffer.Read(iBufferOffset,  typeof ( byte ), LockFlag.FromWriteCursor, locksize);
             //capturedata = g729.Encode(capturedata);//语音编码
             try
             {
                 int  intSet = capturedata.Length;
                 //播放
                 GetVoiceData(intSet,capturedata);
 
                 if  (IsRecord)
                 {
                     // 写入Wav文件
                     mWriter.Write(capturedata, 0, capturedata.Length);
                     // 更新已经录制的数据长度.
                     mSampleCount += capturedata.Length;
                 }
                 //Client.SendTo(capturedata, epServer);//传送语音
             }
             catch
             {
                // throw new Exception();
             }
             iBufferOffset += capturedata.Length;
             iBufferOffset %= iBufferSize; //取模是因为缓冲区是循环的。
         }
 
 
/// <summary>
         /// 从字节数组中获取音频数据,并进行播放
         /// </summary>
         /// <param name="intRecv">字节数组长度</param>
         /// <param name="bytRecv">包含音频数据的字节数组</param>
         public  void  GetVoiceData( int  intRecv,  byte [] bytRecv)
         {
             //intPosWrite指示最新的数据写好后的末尾。intPosPlay指示本次播放开始的位置。
             if  (intPosWrite + intRecv <= memstream.Capacity)
             { //如果当前写指针所在的位移+将要写入到缓冲区的长度小于缓冲区总大小
                 if  ((intPosWrite - intPosPlay >= 0 && intPosWrite - intPosPlay < intNotifySize) || (intPosWrite - intPosPlay < 0 && intPosWrite - intPosPlay + memstream.Capacity < intNotifySize))
                 {
                     memstream.Write(bytRecv, 0, intRecv);
                     intPosWrite += intRecv;
 
                 }
                 else  if  (intPosWrite - intPosPlay >= 0)
                 { //先存储一定量的数据,当达到一定数据量时就播放声音。
                     buffDiscript.BufferBytes =  intPosWrite - intPosPlay; //缓冲区大小为播放指针到写指针之间的距离。
                     SecondaryBuffer sec =  new  SecondaryBuffer(buffDiscript, PlayDev); //建立一个合适的缓冲区用于播放这段数据。
                     memstream.Position = intPosPlay; //先将memstream的指针定位到这一次播放开始的位置
                     sec.Write(0, memstream, intPosWrite - intPosPlay, LockFlag.FromWriteCursor);
                     sec.Play(0, BufferPlayFlags.Default);
                    
                     memstream.Position = intPosWrite; //写完后重新将memstream的指针定位到将要写下去的位置。
                     intPosPlay = intPosWrite;
                 }
                 else  if  (intPosWrite - intPosPlay < 0)
                 {
                     buffDiscript.BufferBytes = intPosWrite - intPosPlay + memstream.Capacity; //缓冲区大小为播放指针到写指针之间的距离。
                     SecondaryBuffer sec =  new  SecondaryBuffer(buffDiscript, PlayDev); //建立一个合适的缓冲区用于播放这段数据。
                     memstream.Position = intPosPlay;
                     sec.Write(0, memstream, memstream.Capacity - intPosPlay, LockFlag.FromWriteCursor);
                     memstream.Position = 0;
                     sec.Write(memstream.Capacity - intPosPlay, memstream, intPosWrite, LockFlag.FromWriteCursor);
                     sec.Play(0, BufferPlayFlags.Default);
                     memstream.Position = intPosWrite;
                     intPosPlay = intPosWrite;
                 }
             }
             else
             { //当数据将要大于memstream可容纳的大小时
                 int  irest = memstream.Capacity - intPosWrite; //memstream中剩下的可容纳的字节数。
                 memstream.Write(bytRecv, 0, irest); //先写完这个内存流。
                 memstream.Position = 0; //然后让新的数据从memstream的0位置开始记录
                 memstream.Write(bytRecv, irest, intRecv - irest); //覆盖旧的数据
                 intPosWrite = intRecv - irest; //更新写指针位置。写指针指示下一个开始写入的位置而不是上一次结束的位置,因此不用减一
             }
         }

你可能感兴趣的:(DI)