Skip to content

Instantly share code, notes, and snippets.

@ermau
Created June 26, 2011 03:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ermau/1047203 to your computer and use it in GitHub Desktop.
Save ermau/1047203 to your computer and use it in GitHub Desktop.
/* This code is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details. */
public class SilverlightAudioCaptureDeviceProvider
{
public SilverlightAudioCaptureDeviceProvider()
{
if (!CaptureDeviceConfiguration.AllowedDeviceAccess)
CaptureDeviceConfiguration.RequestDeviceAccess();
UpdateDevices();
this.pollTimer.Interval = TimeSpan.FromMilliseconds (250);
this.pollTimer.Tick += PollTimerOnTick;
this.pollTimer.Start();
}
public event EventHandler DefaultDeviceChanged;
public AudioCaptureDeviceEx DefaultDevice
{
get;
private set;
}
public IEnumerable<AudioCaptureDeviceEx> AudioDevices
{
get
{
lock (this.devices)
return this.devices.Values.Where (d => d.IsAvailable).ToList();
}
}
private readonly DispatcherTimer pollTimer = new DispatcherTimer();
private readonly Dictionary<AudioCaptureDevice, AudioCaptureDeviceEx> devices =
new Dictionary<AudioCaptureDevice, AudioCaptureDeviceEx> (AudioCaptureDeviceEqualityComparer.Instance);
private void PollTimerOnTick (object sender, EventArgs eventArgs)
{
UpdateDevices();
}
private class AudioCaptureDeviceEqualityComparer
: IEqualityComparer<AudioCaptureDevice>
{
public static readonly AudioCaptureDeviceEqualityComparer Instance = new AudioCaptureDeviceEqualityComparer();
public bool Equals (AudioCaptureDevice x, AudioCaptureDevice y)
{
if (x == y)
return true;
if (x == null || y == null)
return false;
return (x.FriendlyName == y.FriendlyName);
}
public int GetHashCode (AudioCaptureDevice obj)
{
if (obj == null)
throw new ArgumentNullException ("obj");
return obj.FriendlyName.GetHashCode();
}
}
private void UpdateDevices()
{
AudioCaptureDevice currentDefault = CaptureDeviceConfiguration.GetDefaultAudioCaptureDevice();
AudioCaptureDeviceEx currentDefaultEx = null;
lock (this.devices)
{
var newDevices = new HashSet<AudioCaptureDevice> (CaptureDeviceConfiguration.GetAvailableAudioCaptureDevices(),
AudioCaptureDeviceEqualityComparer.Instance);
foreach (var kvp in this.devices)
{
if (currentDefault != null && kvp.Value.FriendlyName == currentDefault.FriendlyName)
currentDefaultEx = kvp.Value;
if (newDevices.Remove (kvp.Key))
{
kvp.Value.IsAvailable = true;
continue;
}
this.devices[kvp.Key].IsAvailable = false;
}
foreach (AudioCaptureDevice device in newDevices)
{
var d = new AudioCaptureDeviceEx (device);
if (currentDefault != null && d.FriendlyName == currentDefault.FriendlyName)
currentDefaultEx = d;
this.devices.Add (device, d);
}
}
if (DefaultDevice != currentDefaultEx)
{
DefaultDevice = currentDefaultEx;
OnDefaultDeviceChanged (EventArgs.Empty);
}
}
private void OnDefaultDeviceChanged (EventArgs e)
{
var changed = DefaultDeviceChanged;
if (changed != null)
changed (this, e);
}
}
public class AudioCaptureDeviceEx
{
public AudioCaptureDeviceEx (AudioCaptureDevice device)
{
if (device == null)
throw new ArgumentNullException ("device");
this.device = device;
}
public event EventHandler IsAvailableChanged;
public bool IsAvailable
{
get { return this.isAvailable; }
set
{
if (this.isAvailable == value)
return;
this.isAvailable = value;
var changed = IsAvailableChanged;
if (changed != null)
changed (this, EventArgs.Empty);
}
}
public bool IsDefaultDevice
{
get { return this.device.IsDefaultDevice; }
}
public string FriendlyName
{
get { return this.device.FriendlyName; }
}
public ReadOnlyCollection<AudioFormat> SupportedFormats
{
get { return this.device.SupportedFormats; }
}
public AudioFormat DesiredFormat
{
get { return this.device.DesiredFormat; }
set { this.device.DesiredFormat = value; }
}
public int AudioFrameSize
{
get { return this.device.AudioFrameSize; }
set { this.device.AudioFrameSize = value; }
}
public static implicit operator AudioCaptureDevice (AudioCaptureDeviceEx captureDevice)
{
return captureDevice.device;
}
private readonly AudioCaptureDevice device;
private bool isAvailable = true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment