下面这个类是用Microsoft.DirectX和Microsoft.DirectSound来实现音频采集的,但采集出来之后的音频质量超烂,嚣叫声很厉害,总有翁翁声的,听得人都想发疯。有哪位前辈做过DirectX下的高质量音频采集,来指点小弟一下,谢谢!顶者有分!!   public  class clsDirectSound
   {
       #region  //类成员变量定义       private MemoryStream memstream;//内存流
       private SecondaryBuffer secBuffer;//辅助缓冲区
       private int iNotifySize = 0;//通知大小
       private int iBufferSize = 0;//捕捉缓冲区大小 
       private CaptureBuffer capturebuffer;//捕捉缓冲区对象
       private AutoResetEvent notifyEvent;//通知事件
       private Thread notifyThread;//通知线程
       private int iNotifyNum = 0;//通知个数
       private Notify myNotify;//通知对象
       private Capture capture;//捕捉设备对象
       private Device PlayDev;//播放设备对象
       private BufferDescription buffDiscript;
       private Socket Client;
       private EndPoint epServer;
       private int iBufferOffset = 0;//捕捉缓冲区位移
       private IntPtr intptr;//窗口句柄
       #endregion       #region //类成员函数定义       #region //创建采集及播放设备
       /// <summary>
       /// 创建捕捉设备对象
       /// </summary>
       /// <returns>如果创建成功返回true</returns>
       private bool CreateCaputerDevice()
       {
           //首先要玫举可用的捕捉设备
           CaptureDevicesCollection capturedev = new CaptureDevicesCollection();
           Guid devguid;
           if (capturedev.Count > 0)
           {
               devguid = capturedev[1].DriverGuid;
           }
           else
           {
               System.Windows.Forms.MessageBox.Show("当前没有可用于音频捕捉的设备", "系统提示");
               return false;
           }
           //利用设备GUID来建立一个捕捉设备对象
           this.capture = new Capture(devguid);
           return true;
       }       /// <summary>
       /// 创建用于播放的音频设备对象
       /// </summary>
       /// <returns>创建成功返回true</returns>
       private bool CreatePlayDevice()
       {
           DevicesCollection dc = new DevicesCollection();
           Guid g;
           if (dc.Count > 0)
           {
               g = dc[1].DriverGuid;
           }
           else
           { return false; }           this.PlayDev = new Device(g); //播放设备
           PlayDev.SetCooperativeLevel(intptr, CooperativeLevel.Normal);
           return true;
       }
       #endregion       #region//创建采集及播放缓冲区       /// <summary>
       /// 创建捕捉缓冲
       /// </summary>
       private void CreateCaptureBuffer()
       {
           //想要创建一个捕捉缓冲区必须要两个参数:缓冲区信息(描述这个缓冲区中的格式等),缓冲设备。
           WaveFormat mWavFormat = SetWaveFormat();
           CaptureBufferDescription bufferdescription = new CaptureBufferDescription();
           bufferdescription.Format = mWavFormat;//设置缓冲区要捕捉的数据格式
           iNotifySize = mWavFormat.AverageBytesPerSecond / iNotifyNum;//1秒的数据量/设置的通知数得到的每个通知大小小于0.2s的数据量,话音延迟小于200ms为优质话音
           iBufferSize = iNotifyNum * iNotifySize;
           bufferdescription.BufferBytes = iBufferSize;
           bufferdescription.ControlEffects = true;
           bufferdescription.WaveMapped = true;           this.capturebuffer= new CaptureBuffer(bufferdescription, capture);//建立设备缓冲区对象       }       /// <summary>
       /// 创建播放缓冲
       /// </summary>
       private void CreateSecondaryBuffer()
       {
           buffDiscript = new BufferDescription();
           WaveFormat mWavFormat = SetWaveFormat();
           buffDiscript.Format = mWavFormat;
           iNotifySize = mWavFormat.AverageBytesPerSecond / iNotifyNum;//设置通知大小
           iBufferSize = iNotifyNum * iNotifySize;
           buffDiscript.BufferBytes = iBufferSize;
           buffDiscript.ControlPan = true;
           buffDiscript.ControlFrequency = true;
           buffDiscript.ControlVolume = true;
           buffDiscript.GlobalFocus = true;
           secBuffer = new SecondaryBuffer(buffDiscript, PlayDev);
           byte[] bytMemory = new byte[100000];
           this.memstream= new MemoryStream(bytMemory, 0, 100000, true, true);
           //g729 = new G729();
           //g729.InitalizeEncode();
           //g729.InitalizeDecode();
       }       #endregion       #region  //设置通知对像
       //设置通知
       private void CreateNotification()
       {
           BufferPositionNotify[] bpn = new BufferPositionNotify[iNotifyNum];//设置缓冲区通知个数
           //设置通知事件
           notifyEvent = new AutoResetEvent(false);
           notifyThread = new Thread(RecoData);//通知触发事件
           notifyThread.IsBackground = true;
           notifyThread.Start();
           for (int i = 0; i < iNotifyNum; i++)
           {
               bpn[i].Offset = iNotifySize + i * iNotifySize - 1;//设置具体每个的位置
               bpn[i].EventNotifyHandle = notifyEvent.Handle;
           }
           this.myNotify = new Notify(capturebuffer);
           myNotify.SetNotificationPositions(bpn);       }
       //线程中的事件
       private void RecoData()
       {
           while (true)
           {
               // 等待缓冲区的通知消息
               notifyEvent.WaitOne(Timeout.Infinite, true);
               // 录制数据
               RecordCapturedData();
           }
       }       //真正转移数据的事件,其实就是把数据传送到网络上去。
       private void RecordCapturedData()
       {
           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.None, locksize);
           try
           {
               
               if (this.audioCaptured != null)  //调用事件订阅者处理程序
               {
                //事件订阅者主要是先对capturedata进行g729编码,
                 //再通过udp发到网络上去
                this.audioCaptured(capturedata);
               }
           }
           catch(Exception ex)
           {
               clsErrorLog.ErrorLog(Application.StartupPath, ex.ToString());
               clsErrorLog.ErrorLog(Application.StartupPath, "调用上层程序处理采集到的音频数据失败");
              
           }
           iBufferOffset += capturedata.Length;
           iBufferOffset %= iBufferSize;//取模是因为缓冲区是循环的。
       }       #endregion
        
       /// <summary>
       /// 启动采集
       /// </summary>
        public void StartVoiceCapture()
        {
            this.capturebuffer.Start(true);//true表示设置缓冲区为循环方式,开始捕捉
        }
       /// <summary>
       /// 初始化相关操作
       /// </summary>
       public void InitVoice()
       {//初始化声音相关设置:(1)捕捉缓冲区(2)播放缓冲区
           if (!CreateCaputerDevice())
           {
              
               //clsErrorLog.ErrorLog(Application.StartupPath, "创建捕捉设备失败");
               clsErrorLog.ErrorLog(Application.StartupPath, "创建捕捉设备失败");
                throw new Exception();
              
           }//建立设备对象
           CreateCaptureBuffer();//创建捕捉缓冲           CreateNotification();//设置通知及事件
           //======(2)==============
           if (!CreatePlayDevice())
           {
               clsErrorLog.ErrorLog(Application.StartupPath, "创建播放设备失败");
               throw new Exception();
           }
           CreateSecondaryBuffer(); //创建播放缓冲 
       }
       #endregion   }
}