- using System;
- using System.Collections.Generic;
- using System.Text;
-
- using System.IO;
- using System.Threading;
- using Microsoft.DirectX;
- using Microsoft.DirectX.DirectSound;
- using System.Net.Sockets;
- using System.Net;
-
- namespace MatureVoice
- {
- class VoiceCapture
- {
- 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;
-
- public IntPtr Intptr
- {
- set
- {
- intptr = value;
- }
- }
-
- public int NotifySize
- {
- set
- {
- iNotifySize = value;
- }
-
- }
-
- public int NotifyNum
- {
- set
- {
- iNotifyNum = value;
- }
- }
-
- public Socket LocalSocket
- {
- set
- {
- Client = value;
- }
- }
-
- public EndPoint RemoteEndPoint
- {
- set
- {
- epServer = value;
- }
- }
-
-
-
-
-
- public void InitVoice()
- {
- if (!CreateCaputerDevice())
- {
- throw new Exception();
- }
- CreateCaptureBuffer();
- CreateNotification();
-
- if (!CreatePlayDevice())
- {
- throw new Exception();
- }
- CreateSecondaryBuffer();
- }
-
-
-
-
- public void StartVoiceCapture()
- {
- capturebuffer.Start(true);
- }
-
-
-
-
-
- private bool CreatePlayDevice()
- {
- DevicesCollection dc = new DevicesCollection();
- Guid g;
- if (dc.Count > 0)
- {
- g = dc[0].DriverGuid;
- }
- else
- { return false; }
- PlayDev = new Device(g);
- PlayDev.SetCooperativeLevel(intptr, CooperativeLevel.Normal);
- return true;
- }
-
-
-
-
- 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];
- memstream = new MemoryStream(bytMemory, 0, 100000, true, true);
-
-
-
- }
-
-
-
-
-
- private bool CreateCaputerDevice()
- {
-
- CaptureDevicesCollection capturedev = new CaptureDevicesCollection();
- Guid devguid;
- if (capturedev.Count > 0)
- {
- devguid = capturedev[0].DriverGuid;
- }
- else
- {
- System.Windows.Forms.MessageBox.Show("当前没有可用于音频捕捉的设备", "系统提示");
- return false;
- }
-
- capture = new Capture(devguid);
- return true;
- }
-
-
-
-
- private void CreateCaptureBuffer()
- {
-
- WaveFormat mWavFormat = SetWaveFormat();
- CaptureBufferDescription bufferdescription = new CaptureBufferDescription();
- bufferdescription.Format = mWavFormat;
- iNotifySize = mWavFormat.AverageBytesPerSecond / iNotifyNum;
- iBufferSize = iNotifyNum * iNotifySize;
- bufferdescription.BufferBytes = iBufferSize;
- bufferdescription.ControlEffects = true;
- bufferdescription.WaveMapped = true;
- capturebuffer = new CaptureBuffer(bufferdescription, capture);
-
- }
-
-
- 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;
- }
- myNotify = new Notify(capturebuffer);
- myNotify.SetNotificationPositions(bpn);
-
- }
-
-
- private void RecoData()
- {
- while (true)
- {
-
- notifyEvent.WaitOne(Timeout.Infinite, true);
-
- RecordCapturedData(Client,epServer);
- }
- }
-
-
- 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)
- {
- locksize += iBufferSize;
- }
- capturedata = (byte[])capturebuffer.Read(iBufferOffset, typeof(byte), LockFlag.FromWriteCursor, locksize);
-
- try
- {
- Client.SendTo(capturedata, epServer);
- }
- catch
- {
- throw new Exception();
- }
- iBufferOffset += capturedata.Length;
- iBufferOffset %= iBufferSize;
- }
-
-
- private int intPosWrite = 0;
- private int intPosPlay = 0;
- private int intNotifySize = 5000;
-
-
-
-
-
-
- public void GetVoiceData(int intRecv, byte[] bytRecv)
- {
-
- 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;
- sec.Write(0, memstream, intPosWrite - intPosPlay, LockFlag.FromWriteCursor);
- sec.Play(0, BufferPlayFlags.Default);
- memstream.Position = intPosWrite;
- 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
- {
- int irest = memstream.Capacity - intPosWrite;
- memstream.Write(bytRecv, 0, irest);
- memstream.Position = 0;
- memstream.Write(bytRecv, irest, intRecv - irest);
- intPosWrite = intRecv - irest;
- }
- }
-
-
-
-
-
- private WaveFormat SetWaveFormat()
- {
- WaveFormat format = new WaveFormat();
- format.FormatTag = WaveFormatTag.Pcm;
- format.SamplesPerSecond = 11025;
- format.BitsPerSample = 16;
- format.Channels = 1;
- format.BlockAlign = (short)(format.Channels * (format.BitsPerSample / 8));
- format.AverageBytesPerSecond = format.BlockAlign * format.SamplesPerSecond;
-
- return format;
-
- }
-
-
-
-
- public void Stop()
- {
- capturebuffer.Stop();
- if (notifyEvent != null)
- {
- notifyEvent.Set();
- }
- if (notifyThread != null && notifyThread.IsAlive == true)
- {
- notifyThread.Abort();
- }
- }
- }
- }
|