public AudioOutputDevice(Guid device, IntPtr owner, int samplingRate, int channels)
{
this.owner = owner;
this.samplingRate = samplingRate;
this.channels = channels;
this.device = device;
DirectSound ds = new DirectSound(device);
ds.SetCooperativeLevel(owner, CooperativeLevel.Priority);
// Set the output format
WaveFormat waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(samplingRate, channels);
bufferSize = 8 * waveFormat.AverageBytesPerSecond;
// Setup the secondary buffer
SoundBufferDescription desc2 = new SoundBufferDescription();
desc2.Flags =
BufferFlags.GlobalFocus |
BufferFlags.ControlPositionNotify |
BufferFlags.GetCurrentPosition2;
desc2.BufferBytes = bufferSize;
desc2.Format = waveFormat;
buffer = new SecondarySoundBuffer(ds, desc2);
var list = new List<NotificationPosition>();
int numberOfPositions = 32;
// Set notification for buffer percentiles
for (int i = 0; i < numberOfPositions; i++)
{
list.Add(new NotificationPosition()
{
WaitHandle = new AutoResetEvent(false),
Offset = i * bufferSize / numberOfPositions + 1,
});
}
// Set notification for end of buffer
list.Add(new NotificationPosition()
{
Offset = bufferSize - 1,
WaitHandle = new AutoResetEvent(false)
});
firstHalfBufferIndex = numberOfPositions / 2;
secondHalfBufferIndex = numberOfPositions;
notifications = list.ToArray();
Accord.Diagnostics.Debug.Assert(notifications[firstHalfBufferIndex].Offset == bufferSize / 2 + 1);
Accord.Diagnostics.Debug.Assert(notifications[secondHalfBufferIndex].Offset == bufferSize - 1);
// Make a copy of the wait handles
waitHandles = new WaitHandle[notifications.Length];
for (int i = 0; i < notifications.Length; i++)
waitHandles[i] = notifications[i].WaitHandle;
// Store all notification positions
buffer.SetNotificationPositions(notifications);
}