Skip to content

Commit

Permalink
fixed a negative volume bug
Browse files Browse the repository at this point in the history
corrected the ugly constant naming scheme.

Removed a forced GC after set defaults
  • Loading branch information
xenolightning committed Jul 5, 2016
1 parent bfe9b9c commit 2a9770e
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 98 deletions.
44 changes: 37 additions & 7 deletions AudioSwitcher.AudioApi.CoreAudio.Tests/DeviceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@ public void Device_Set_Volume_2()

}

[Fact]
public void Device_Set_Volume_Negative_Is_Zero()
{
using (var controller = CreateTestController())
{
var currentVolume = controller.DefaultPlaybackDevice.Volume;

controller.DefaultPlaybackDevice.Volume = -5;

Assert.Equal(0, (int)controller.DefaultPlaybackDevice.Volume);

controller.DefaultPlaybackDevice.Volume = currentVolume;
}

}

[Fact]
public async Task Device_Set_Volume_Async()
{
Expand Down Expand Up @@ -76,6 +92,22 @@ public async Task Device_Set_Volume_Async_2()

}

[Fact]
public async Task Device_Set_Volume_Async_Negative_Is_Zero()
{
using (var controller = CreateTestController())
{
var currentVolume = controller.DefaultPlaybackDevice.Volume;

await controller.DefaultPlaybackDevice.SetVolumeAsync(-5);

Assert.Equal(0, (int)controller.DefaultPlaybackDevice.Volume);

await controller.DefaultPlaybackDevice.SetVolumeAsync(currentVolume);
}

}

[Fact]
public void Device_Set_Default()
{
Expand Down Expand Up @@ -191,28 +223,26 @@ public async Task Device_Set_Default_Communications_Async_Returns_In_Order()
{
var order = new ConcurrentQueue<int>();
var device = controller.DefaultPlaybackCommunicationsDevice;
var current = 1;

var t1 = device.SetAsDefaultCommunicationsAsync().ContinueWith(x =>
{
order.Enqueue(1);
order.Enqueue(current++);
});

await Task.Delay(5);
var t2 = device.SetAsDefaultCommunicationsAsync().ContinueWith(x =>
{
order.Enqueue(2);
order.Enqueue(current++);
});

await Task.Delay(5);
var t3 = device.SetAsDefaultCommunicationsAsync().ContinueWith(x =>
{
order.Enqueue(3);
order.Enqueue(current++);
});

await Task.Delay(5);
var t4 = device.SetAsDefaultCommunicationsAsync().ContinueWith(x =>
{
order.Enqueue(4);
order.Enqueue(current++);
});

await Task.WhenAll(t1, t2, t3, t4);
Expand Down
33 changes: 20 additions & 13 deletions AudioSwitcher.AudioApi.CoreAudio/CoreAudioDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace AudioSwitcher.AudioApi.CoreAudio
{
public sealed partial class CoreAudioDevice : Device
{
private const int DEFAULT_COM_TIMEOUT = 500;
private const int DefaultComTimeout = 500;

private static readonly Dictionary<PropertyKey, HashSet<string>> PropertykeyToPropertyMap = new Dictionary<PropertyKey, HashSet<string>>
{
Expand Down Expand Up @@ -154,8 +154,13 @@ public override double Volume
if (AudioEndpointVolume == null)
return;

AudioEndpointVolume.MasterVolumeLevelScalar = NormailizeVolume(value);
_volumeResetEvent.Wait(DEFAULT_COM_TIMEOUT);
var normalizedVolume = NormalizeVolume(value);

if (Math.Abs(_volume - normalizedVolume) < 0.1)
return;

AudioEndpointVolume.MasterVolumeLevelScalar = normalizedVolume;
_volumeResetEvent.Wait(DefaultComTimeout);
}
}

Expand Down Expand Up @@ -265,7 +270,7 @@ public override bool Mute(bool mute)
return true;

AudioEndpointVolume.Mute = mute;
_muteChangedResetEvent.Wait(DEFAULT_COM_TIMEOUT);
_muteChangedResetEvent.Wait(DefaultComTimeout);

return _isMuted;
}
Expand All @@ -279,26 +284,28 @@ public override async Task<bool> MuteAsync(bool mute)
return true;

AudioEndpointVolume.Mute = mute;
await _muteChangedResetEvent.WaitAsync(DEFAULT_COM_TIMEOUT);
await _muteChangedResetEvent.WaitAsync(DefaultComTimeout);

return _isMuted;
}

public override async Task<double> SetVolumeAsync(double volume)
{
if (Math.Abs(_volume - volume) < 0.1)
var normalizedVolume = NormalizeVolume(volume);

if (Math.Abs(_volume - normalizedVolume) < 0.1)
return _volume;

if (AudioEndpointVolume == null)
return -1;

AudioEndpointVolume.MasterVolumeLevelScalar = NormailizeVolume(volume);
await _volumeResetEvent.WaitAsync(DEFAULT_COM_TIMEOUT);
AudioEndpointVolume.MasterVolumeLevelScalar = normalizedVolume;
await _volumeResetEvent.WaitAsync(DefaultComTimeout);

return _volume;
}

private static float NormailizeVolume(double volume)
private static float NormalizeVolume(double volume)
{
if (volume <= 0)
volume = 0;
Expand All @@ -313,7 +320,7 @@ private static float NormailizeVolume(double volume)
public override bool SetAsDefault()
{
var cts = new CancellationTokenSource();
cts.CancelAfter(DEFAULT_COM_TIMEOUT);
cts.CancelAfter(DefaultComTimeout);

return SetAsDefault(cts.Token);
}
Expand Down Expand Up @@ -351,7 +358,7 @@ public override bool SetAsDefault(CancellationToken cancellationToken)
public override Task<bool> SetAsDefaultAsync()
{
var cts = new CancellationTokenSource();
cts.CancelAfter(DEFAULT_COM_TIMEOUT);
cts.CancelAfter(DefaultComTimeout);

return SetAsDefaultAsync(cts.Token);
}
Expand Down Expand Up @@ -392,15 +399,15 @@ public override async Task<bool> SetAsDefaultAsync(CancellationToken cancellatio
public override bool SetAsDefaultCommunications()
{
var cts = new CancellationTokenSource();
cts.CancelAfter(DEFAULT_COM_TIMEOUT);
cts.CancelAfter(DefaultComTimeout);

return SetAsDefaultCommunications(cts.Token);
}

public override Task<bool> SetAsDefaultCommunicationsAsync()
{
var cts = new CancellationTokenSource();
cts.CancelAfter(DEFAULT_COM_TIMEOUT);
cts.CancelAfter(DefaultComTimeout);

return SetAsDefaultCommunicationsAsync(cts.Token);
}
Expand Down
4 changes: 2 additions & 2 deletions AudioSwitcher.AudioApi.CoreAudio/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace AudioSwitcher.AudioApi.CoreAudio
{
public static class Extensions
{
private const string GUID_REGEX =
private const string GuidRegex =
@"([a-fA-F0-9]{8}[-][a-fA-F0-9]{4}[-][a-fA-F0-9]{4}[-][a-fA-F0-9]{4}[-][a-fA-F0-9]{12})";

internal static EDataFlow AsEDataFlow(this DeviceType type)
Expand Down Expand Up @@ -110,7 +110,7 @@ internal static Role AsRole(this ERole role)

internal static IEnumerable<Guid> ExtractGuids(this string str)
{
var r = new Regex(GUID_REGEX);
var r = new Regex(GuidRegex);
var matches = r.Matches(str);

if (matches.Count == 0)
Expand Down
2 changes: 0 additions & 2 deletions AudioSwitcher.AudioApi.CoreAudio/Internal/PolicyConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ public static void SetDefaultEndpoint(string devId, ERole eRole)
{
if (policyConfig != null && Marshal.IsComObject(policyConfig))
Marshal.FinalReleaseComObject(policyConfig);

GC.Collect();
}
}
}
Expand Down
Loading

0 comments on commit 2a9770e

Please sign in to comment.