C#中使用DirectSound来获取麦克音量,该如何解决
C#中使用DirectSound来获取麦克音量
大家好,我最近在做一个程序需要使用DirectSound, 当用户说话时我要开始录音,当用户说完了自动停止录音,然后这样循环下去.
现在的问题是如何知道用户是否在说话.请下看下以下代码:
上面的代码是C# DirectSound的捕获到数据后的处理方法.也就是说,麦克风得到的信号转换成数字信号,在程序里变为一个byte[]数组放到缓存区,然后我可以一个一个的从缓冲区里得到这个byte[]对象,以前我在这里提问过,一些朋友说计算这个byte[]的平均值或方差可以得到用户说话的音量,可是效果不理想.有时好用有时不好用.
所以来到这里请大家帮忙!是否有办法通过计算缓冲区得到的byte[]数据来得到麦克音量,或通过其他API(最好是DirectSound的)能知道用户当前的说话的音量大小.无论你能否帮上忙,先谢谢你!
以下的信息或许会有帮助:
1.我找到的声音探测的软件(含源码),不过功能太复杂了,不容易分离出来,并且使用的不是DirectSound如果用他的整个程序得重写.
http://www.dreamincode.net/forums/showtopic38890.htm
2.我已经完成的不带自动探测声音的录音的源代码
大家好,我最近在做一个程序需要使用DirectSound, 当用户说话时我要开始录音,当用户说完了自动停止录音,然后这样循环下去.
现在的问题是如何知道用户是否在说话.请下看下以下代码:
- C# code
private void RecordCapturedData() { byte[] CaptureData = null; int ReadPos; int CapturePos; int LockSize; mRecBuffer.GetCurrentPosition(out CapturePos, out ReadPos); LockSize = ReadPos - mNextCaptureOffset; if (LockSize < 0) LockSize += mBufferSize; LockSize -= (LockSize % mNotifySize); if (0 == LockSize) return; CaptureData = (byte[])mRecBuffer.Read(mNextCaptureOffset, typeof(byte), LockFlag.None, LockSize); mNextCaptureOffset += CaptureData.Length; mNextCaptureOffset %= mBufferSize; //check state if (state == State.Recording || state == State.PreRecording) { secondBuffer.Add(CaptureData); } }
上面的代码是C# DirectSound的捕获到数据后的处理方法.也就是说,麦克风得到的信号转换成数字信号,在程序里变为一个byte[]数组放到缓存区,然后我可以一个一个的从缓冲区里得到这个byte[]对象,以前我在这里提问过,一些朋友说计算这个byte[]的平均值或方差可以得到用户说话的音量,可是效果不理想.有时好用有时不好用.
所以来到这里请大家帮忙!是否有办法通过计算缓冲区得到的byte[]数据来得到麦克音量,或通过其他API(最好是DirectSound的)能知道用户当前的说话的音量大小.无论你能否帮上忙,先谢谢你!
以下的信息或许会有帮助:
1.我找到的声音探测的软件(含源码),不过功能太复杂了,不容易分离出来,并且使用的不是DirectSound如果用他的整个程序得重写.
http://www.dreamincode.net/forums/showtopic38890.htm
2.我已经完成的不带自动探测声音的录音的源代码
- C# code
public class Recorder { //由于长度限制,变量略 public void Initialize() { // Create capture buffer. CreateCaptureBuffer(); // Create notification system. InitNotifications(); mRecBuffer.Start(true); } public void Dispose() { // Close notification if (null != mNotificationEvent) mNotificationEvent.Set(); // Stop recording mRecBuffer.Stop(); } #endregion #region Initialize Recorder public Recorder() { InitCaptureDevice(); mWavFormat = CreateWaveFormat(); buffDes = new BufferDescription(); buffDes.GlobalFocus = true; buffDes.ControlVolume = true; buffDes.ControlPan = true; secDev = new Device(); bufferStates = new List<int>(); } private void RecordCapturedData() { byte[] CaptureData = null; int ReadPos; int CapturePos; int LockSize; mRecBuffer.GetCurrentPosition(out CapturePos, out ReadPos); LockSize = ReadPos - mNextCaptureOffset; if (LockSize < 0) LockSize += mBufferSize; LockSize -= (LockSize % mNotifySize); if (0 == LockSize) return; CaptureData = (byte[])mRecBuffer.Read(mNextCaptureOffset, typeof(byte), LockFlag.None, LockSize); mNextCaptureOffset += CaptureData.Length; mNextCaptureOffset %= mBufferSize; //check state if (state == State.Recording || state == State.PreRecording) { secondBuffer.Add(CaptureData); } } private void CreateCaptureBuffer() { CaptureBufferDescription bufferdescription = new CaptureBufferDescription(); if (null != mNotify) { mNotify.Dispose(); mNotify = null; } if (null != mRecBuffer) { mRecBuffer.Dispose(); mRecBuffer = null; } // set notification's size: 1 second mNotifySize = (1024 > mWavFormat.AverageBytesPerSecond / 8) ? 1024 : (mWavFormat.AverageBytesPerSecond / 8); mNotifySize -= mNotifySize % mWavFormat.BlockAlign; // set size of buffer mBufferSize = mNotifySize * cNotifyNum; bufferdescription.BufferBytes = mBufferSize; bufferdescription.Format = mWavFormat; mRecBuffer = new CaptureBuffer(bufferdescription, mCapDev); mNextCaptureOffset = 0; } private bool InitNotifications() { if (null == mRecBuffer) { MessageBox.Show("Record buffer is not found!"); return false; } mNotificationEvent = new AutoResetEvent(false); if (null == mNotifyThread) { mNotifyThread = new Thread(new ThreadStart(WaitThread)); mNotifyThread.Start(); } BufferPositionNotify[] PositionNotify = new BufferPositionNotify[cNotifyNum + 1]; for (int i = 0; i < cNotifyNum; i++) { PositionNotify[i].Offset = (mNotifySize * i) + mNotifySize - 1; PositionNotify[i].EventNotifyHandle = mNotificationEvent.Handle; } mNotify = new Notify(mRecBuffer); mNotify.SetNotificationPositions(PositionNotify, cNotifyNum); return true; } private bool InitCaptureDevice() { CaptureDevicesCollection devices = new CaptureDevicesCollection(); Guid deviceGuid = Guid.Empty; if (devices.Count > 0) deviceGuid = devices[0].DriverGuid; else { MessageBox.Show("No device to capture wave!"); return false; } try { mCapDev = new Capture(deviceGuid); } catch (DirectXException e) { MessageBox.Show(e.ToString()); return false; } return true; } private WaveFormat CreateWaveFormat() { WaveFormat format = new WaveFormat(); format.FormatTag = WaveFormatTag.Pcm; // PCM format.SamplesPerSecond = 16000; // 16KHz format.BitsPerSample = 16; // 16Bit format.Channels = 1; // Mono format.BlockAlign = (short)(format.Channels * (format.BitsPerSample / 8)); format.AverageBytesPerSecond = format.BlockAlign * format.SamplesPerSecond; return format; } private void WaitThread() { while (true) { // waiting for notification mNotificationEvent.WaitOne(Timeout.Infinite, true); // process data captured RecordCapturedData(); } } #endregion }