Skip to content

Commit

Permalink
Minor improvements accross a range of components
Browse files Browse the repository at this point in the history
  • Loading branch information
xenolightning committed Sep 16, 2016
1 parent 5008f61 commit 0305869
Show file tree
Hide file tree
Showing 20 changed files with 197 additions and 182 deletions.
58 changes: 22 additions & 36 deletions AudioSwitcher.AudioApi.CoreAudio/CoreAudioController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,24 @@ public CoreAudioController()
{
// ReSharper disable once SuspiciousTypeConversion.Global
_innerEnumerator = ComObjectFactory.GetDeviceEnumerator();
_systemEvents = new SystemEventNotifcationClient(_innerEnumerator);

if (_innerEnumerator == null)
return;

_systemEvents = new SystemEventNotifcationClient(_innerEnumerator);

_systemEvents.DeviceAdded.Subscribe(x => OnDeviceAdded(x.DeviceId));
_systemEvents.DeviceRemoved.Subscribe(x => OnDeviceRemoved(x.DeviceId));
});

RefreshSystemDevices();
_deviceCache = new HashSet<CoreAudioDevice>();
IMultimediaDeviceCollection collection;
_innerEnumerator.EnumAudioEndpoints(EDataFlow.All, EDeviceState.All, out collection);

using (var coll = new MultimediaDeviceCollection(collection))
{
foreach (var mDev in coll)
CacheDevice(mDev);
}
});
}

internal SystemEventNotifcationClient SystemEvents => _systemEvents;
Expand Down Expand Up @@ -63,25 +70,20 @@ private void OnDeviceRemoved(string deviceId)

protected override void Dispose(bool disposing)
{
ComThread.BeginInvoke(() =>
if (_systemEvents != null)
{
if (_systemEvents != null)
{
_systemEvents.Dispose();
_systemEvents = null;
}
_systemEvents.Dispose();
_systemEvents = null;
}

_innerEnumerator = null;
})
.ContinueWith(x =>
foreach (var device in _deviceCache)
{
foreach (var device in _deviceCache)
{
device.Dispose();
}
_deviceCache?.Clear();
_lock?.Dispose();
});
device.Dispose();
}

_deviceCache?.Clear();
_lock?.Dispose();
_innerEnumerator = null;

base.Dispose(disposing);

Expand Down Expand Up @@ -120,22 +122,6 @@ private CoreAudioDevice GetDevice(string realId)
}
}

private void RefreshSystemDevices()
{
ComThread.Invoke(() =>
{
_deviceCache = new HashSet<CoreAudioDevice>();
IMultimediaDeviceCollection collection;
_innerEnumerator.EnumAudioEndpoints(EDataFlow.All, EDeviceState.All, out collection);

using (var coll = new MultimediaDeviceCollection(collection))
{
foreach (var mDev in coll)
CacheDevice(mDev);
}
});
}

private CoreAudioDevice GetOrAddDeviceFromRealId(string deviceId)
{
//This pre-check here may prevent more com objects from being created
Expand Down
1 change: 1 addition & 0 deletions AudioSwitcher.AudioApi.CoreAudio/CoreAudioDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ protected override void Dispose(bool disposing)
{
if (!_isDisposed)
{
_properties?.Dispose();
_peakValueTimerSubscription?.Dispose();

ComThread.BeginInvoke(() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,43 +46,50 @@ internal AudioEndpointVolumeCallback(AudioEndpointVolume handler)

public int OnNotify(IntPtr notifyData)
{
//Since AUDIO_VOLUME_NOTIFICATION_DATA is dynamic in length based on the
//number of audio channels available we cannot just call PtrToStructure
//to get all data, thats why it is split up into two steps, first the static
//data is marshalled into the data structure, then with some IntPtr math the
//remaining floats are read from memory.
//
var data =
(AudioVolumeNotificationDataStruct)
Marshal.PtrToStructure(notifyData, typeof (AudioVolumeNotificationDataStruct));

//Determine offset in structure of the first float
var offset = Marshal.OffsetOf(typeof (AudioVolumeNotificationDataStruct), "ChannelVolume");
//Determine offset in memory of the first float
var firstFloatPtr = (IntPtr) ((long) notifyData + (long) offset);

//Something weird happened, better to ignore it and move on
if (data.Channels > 100)
return 0;

var voldata = new float[data.Channels];

//Read all floats from memory.
for (var i = 0; i < data.Channels; i++)
try
{
voldata[i] = (float) Marshal.PtrToStructure(firstFloatPtr, typeof (float));
//Since AUDIO_VOLUME_NOTIFICATION_DATA is dynamic in length based on the
//number of audio channels available we cannot just call PtrToStructure
//to get all data, thats why it is split up into two steps, first the static
//data is marshalled into the data structure, then with some IntPtr math the
//remaining floats are read from memory.
//
var data =
(AudioVolumeNotificationDataStruct)
Marshal.PtrToStructure(notifyData, typeof(AudioVolumeNotificationDataStruct));

//Determine offset in structure of the first float
var offset = Marshal.OffsetOf(typeof(AudioVolumeNotificationDataStruct), "ChannelVolume");
//Determine offset in memory of the first float
var firstFloatPtr = (IntPtr) ((long) notifyData + (long) offset);

//Something weird happened, better to ignore it and move on
if (data.Channels > 100)
return 0;

var voldata = new float[data.Channels];

//Read all floats from memory.
for (var i = 0; i < data.Channels; i++)
{
voldata[i] = (float) Marshal.PtrToStructure(firstFloatPtr, typeof(float));
}

//Create combined structure and Fire Event in parent class.
var notificationData = new AudioVolumeNotificationData(data.EventContext, data.Muted,
data.MasterVolume, voldata);

var p = _handler.Target as AudioEndpointVolume;

if (_handler.IsAlive)
p?.FireNotification(notificationData);
}
catch(Exception ex)
{
return ex.HResult;
}

//Create combined structure and Fire Event in parent class.
var notificationData = new AudioVolumeNotificationData(data.EventContext, data.Muted,
data.MasterVolume, voldata);

var p = _handler.Target as AudioEndpointVolume;

if (_handler.IsAlive)
p?.FireNotification(notificationData);

return 0;
return 0; //success
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ protected WaveFormat(SampleRate rate, BitDepth bits, SpeakerConfiguration channe
{
throw new ArgumentOutOfRangeException(nameof(channelMask), "Channels must be 1 or greater");
}
// minimum 16 bytes, sometimes 18 for PCM
waveFormatTag = WaveFormatEncoding.Pcm;

sampleRate = (int)rate;
bitsPerSample = (short)bits;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,7 @@ internal MultimediaDeviceCollection(IMultimediaDeviceCollection parent)

public void Dispose()
{
if (_multimediaDeviceCollection != null)
{
Marshal.FinalReleaseComObject(_multimediaDeviceCollection);
_multimediaDeviceCollection = null;
}
_multimediaDeviceCollection = null;
}

public IEnumerator<IMultimediaDevice> GetEnumerator()
Expand Down
Loading

0 comments on commit 0305869

Please sign in to comment.