Skip to content

Commit

Permalink
Fix latency and restart bugs
Browse files Browse the repository at this point in the history
Fixed restart mirror option not working at all
Fixed mirror not initializing if a nonexistent audio device was present in the config
Checks for audio devices being ready before initializing mirror
Listens for system resume event to restart mirror automatically after waking from sleep
  • Loading branch information
PseudoResonance committed Aug 4, 2022
1 parent 6eeae24 commit 025a21f
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 11 deletions.
24 changes: 15 additions & 9 deletions AudioMirror.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public void startMirror()
{
capture = new WasapiLoopbackCapture();
MMDevice device = enumerator.GetDevice(settings.selectedInputDeviceId);
if (device != null && device.DeviceState == DeviceState.Active)
if (device.DeviceState == DeviceState.Active)
{
System.Diagnostics.Debug.WriteLine("Starting audio mirror");
capture.Device = device;
Expand Down Expand Up @@ -142,16 +142,22 @@ public void updateOutputs()
{
if (!outputStrings.Contains(id))
{
MMDevice device = enumerator.GetDevice(id);
if (device != null && device.DeviceState == DeviceState.Active)
try
{
WasapiOut output = new WasapiOut(true, AudioClientShareMode.Shared, 5);
output.Device = device;
output.Initialize(source);
output.Play();
outputs.Add(output);
outputStrings.Add(id);
System.Diagnostics.Debug.WriteLine("Searching for: " + id);
MMDevice device = enumerator.GetDevice(id);
System.Diagnostics.Debug.WriteLine("Found Name: " + device.FriendlyName + " State: " + device.DeviceState.ToString());
if (device.DeviceState == DeviceState.Active)
{
WasapiOut output = new WasapiOut(true, AudioClientShareMode.Shared, 5);
output.Device = device;
output.Initialize(source);
output.Play();
outputs.Add(output);
outputStrings.Add(id);
}
}
catch (Exception) { }
}
}
}
Expand Down
82 changes: 80 additions & 2 deletions Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using CSCore.CoreAudioAPI;
using Microsoft.Win32;
using System.Text.Json;

namespace WASAPI_Audio_Mirror
Expand Down Expand Up @@ -41,8 +42,11 @@ static void Main()
outputItem = new ToolStripMenuItem("Output Audio Device");
outputItem.Name = "Output Audio Device";
findAudioDevices();
exclusiveFactory.StartNew(() => audioMirror.startMirror());
exclusiveFactory.StartNew(() => audioMirror.updateOutputs());
if (checkReady())
{
exclusiveFactory.StartNew(() => audioMirror.startMirror());
exclusiveFactory.StartNew(() => audioMirror.updateOutputs());
}
deviceNotification.DeviceAdded += (s, e) => { updateDevices = true; exclusiveFactory.StartNew(() => audioMirror.updateOutputs()); };
deviceNotification.DeviceRemoved += (s, e) => { updateDevices = true; exclusiveFactory.StartNew(() => audioMirror.updateOutputs()); };
deviceNotification.DeviceStateChanged += (s, e) => { updateDevices = true; exclusiveFactory.StartNew(() => audioMirror.updateOutputs()); };
Expand All @@ -67,10 +71,83 @@ static void Main()
trayIcon.Visible = true;
trayIcon.ContextMenuStrip = trayMenu;

SystemEvents.PowerModeChanged += onPowerModeChange;

Application.ApplicationExit += new EventHandler(onExit);
Application.Run();
}

private static bool checkReady()
{
int tries = 0;
bool foundInput = false;
bool foundOutput = false;
while (true)
{
tries++;
try
{
MMDevice device = deviceEnumerator.GetDevice(settings.selectedInputDeviceId);
if (device.DeviceState == DeviceState.Active)
{
foundInput = true;
break;
}
}
catch (Exception) { }
if (tries >= 10)
{
break;
}
Thread.Sleep(5000);
}
if (foundInput)
{
tries = 0;
while (true)
{
tries++;
foreach (string id in settings.selectedOutputDeviceIds)
{
try
{
MMDevice device = deviceEnumerator.GetDevice(id);
if (device.DeviceState == DeviceState.Active)
{
foundOutput = true;
break;
}
}
catch (Exception) { }
}
if (foundOutput || tries >= 10)
{
break;
}
Thread.Sleep(5000);
}
if (foundOutput)
{
return true;
}
}
return false;
}

private static void onPowerModeChange(object? sender, PowerModeChangedEventArgs e)
{
if (e.Mode == PowerModes.Resume)
{
System.Diagnostics.Debug.WriteLine("Detecting system resume from sleep, restarting mirror");
exclusiveFactory.StartNew(() => audioMirror.stopMirror());
if (checkReady())
{
exclusiveFactory.StartNew(() => audioMirror.startMirror());
exclusiveFactory.StartNew(() => audioMirror.updateOutputs());
}
}
}

private static void onPause(object? sender, EventArgs e)
{
if (paused)
Expand Down Expand Up @@ -98,6 +175,7 @@ private static void onRestart(object? sender, EventArgs e)
System.Diagnostics.Debug.WriteLine("Restarting mirror");
exclusiveFactory.StartNew(() => audioMirror.stopMirror());
exclusiveFactory.StartNew(() => audioMirror.startMirror());
exclusiveFactory.StartNew(() => audioMirror.updateOutputs());
}

private static void onExit(object? sender, EventArgs e)
Expand Down

0 comments on commit 025a21f

Please sign in to comment.