[SlimDX] DirectSound: Capture Microphone Stream With Low Latency Example
using System;
using SlimDX;
using SlimDX.DirectSound;
using SlimDX.Multimedia;
using System.IO;
using System.Threading;
using System.Collections.Generic;
namespace CaptureSound
{
class Program
{
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
static extern short GetAsyncKeyState(int key);
const int VK_ESCAPE = 0x1B;
static void Main(string[] args)
{
WaveFormat format = new WaveFormat();
format.FormatTag = WaveFormatTag.Pcm;
format.Channels = 1;
format.BitsPerSample = 16;
format.SamplesPerSecond = 8000;
format.BlockAlignment = (short)(format.BitsPerSample / 8);
format.AverageBytesPerSecond = format.SamplesPerSecond * format.BlockAlignment * format.Channels;
FileStream stream = File.Open("output.raw", FileMode.OpenOrCreate);
SoundBufferDescription primaryBufferDescription = new SoundBufferDescription();
primaryBufferDescription.Format = format;
primaryBufferDescription.Flags = BufferFlags.GlobalFocus;
primaryBufferDescription.SizeInBytes = 2 * format.AverageBytesPerSecond;
// Primary Buffer
DirectSound ds = new DirectSound();
ds.SetCooperativeLevel(System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle, CooperativeLevel.Normal);
// Capture
CaptureBufferDescription captureBufferDescription = new CaptureBufferDescription()
{
Format = format,
BufferBytes = format.AverageBytesPerSecond / 50, // 20ms
WaveMapped = true,
ControlEffects = false,
};
DirectSoundCapture directSoundCapture = new DirectSoundCapture();
CaptureBuffer captureBuffer = new CaptureBuffer(directSoundCapture, captureBufferDescription);
const int bufferPortionCount = 2;
int bufferPortionSize = captureBuffer.SizeInBytes / bufferPortionCount;
List<NotificationPosition> notifications = new List<NotificationPosition>();
for (int i = 0; i < bufferPortionCount; i++)
{
notifications.Add(new NotificationPosition()
{
Offset = bufferPortionSize - 1 + bufferPortionSize * i,
Event = new AutoResetEvent(false),
});
}
captureBuffer.SetNotificationPositions(notifications.ToArray());
WaitHandle[] waitHandles = new WaitHandle[notifications.Count];
for (int i = 0; i < notifications.Count; i++)
{
waitHandles[i] = notifications[i].Event;
}
captureBuffer.Start(true);
byte[] bufferPortion = new byte[bufferPortionSize];
int bufferPortionIndex;
DateTime lastNotificationTime = DateTime.MinValue;
DateTime now;
while (GetAsyncKeyState(VK_ESCAPE) == 0)
{
bufferPortionIndex = WaitHandle.WaitAny(waitHandles);
captureBuffer.Read<byte>(bufferPortion, 0, bufferPortionSize, bufferPortionSize * bufferPortionIndex);
now = DateTime.Now;
System.Diagnostics.Debug.Write(String.Format("{0}\t{1}\n", bufferPortionIndex, (now - lastNotificationTime).Milliseconds));
lastNotificationTime = now;
stream.Write(bufferPortion, 0, bufferPortion.Length);
}
captureBuffer.Stop();
for (int i = 0; i < notifications.Count; i++)
{
notifications[i].Event.Close();
}
captureBuffer.Dispose();
directSoundCapture.Dispose();
ds.Dispose();
stream.Close();
stream.Dispose();
}
}
}
[Edited by - hmassad on November 7, 2010 11:01:16 AM]


















