mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
Added Audio switching and reverting logic
Audio device now correctly switches and reverts. Very happy how easy that was to do. This is an amazing audio library!
This commit is contained in:
parent
1ef91be002
commit
a596c0b252
@ -13,6 +13,7 @@ using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using System.Text.RegularExpressions;
|
||||
using IWshRuntimeLibrary;
|
||||
using AudioSwitcher.AudioApi.CoreAudio;
|
||||
|
||||
namespace DisplayMagician
|
||||
{
|
||||
@ -93,7 +94,6 @@ namespace DisplayMagician
|
||||
[JsonIgnore]
|
||||
public string _savedShortcutIconCacheFilename;
|
||||
|
||||
|
||||
public ShortcutItem()
|
||||
{
|
||||
// Create a new UUID for the shortcut if one wasn't created already
|
||||
@ -1565,19 +1565,45 @@ namespace DisplayMagician
|
||||
}
|
||||
}
|
||||
// If the game is a Uplay Game we check for that
|
||||
/*else if (GameLibrary.Equals(SupportedGameLibrary.Uplay))
|
||||
else if (GameLibrary.Equals(SupportedGameLibrary.Uplay))
|
||||
{
|
||||
// First check if Steam is installed
|
||||
// Check if Steam is installed and error if it isn't
|
||||
if (!UplayLibrary.IsUplayInstalled)
|
||||
{
|
||||
return (false, "Cannot find the Uplay executable! Uplay doesn't appear to be installed");
|
||||
}
|
||||
|
||||
// We need to look up details about the game
|
||||
if (!UplayGame.IsInstalled(GameAppId))
|
||||
if (!UplayLibrary.ContainsUplayGame(GameAppId))
|
||||
{
|
||||
return (false, string.Format("The Uplay Game with AppID '{0}' is not installed on this computer.", GameAppId));
|
||||
}
|
||||
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// Do all the specified pre-start apps still exist?
|
||||
// Check the Audio Device is still valid (if one is specified)
|
||||
if (ChangeAudioDevice)
|
||||
{
|
||||
CoreAudioController audioController = ShortcutRepository.AudioController;
|
||||
IEnumerable<CoreAudioDevice> audioDevices = audioController.GetPlaybackDevices();
|
||||
foreach (CoreAudioDevice audioDevice in audioDevices)
|
||||
{
|
||||
if (audioDevice.FullName.Equals(AudioDevice))
|
||||
{
|
||||
if (audioDevice.State == AudioSwitcher.AudioApi.DeviceState.Disabled)
|
||||
return (false, $"The Audio Device {AudioDevice} is disabled, so the shortcut '{Name}' cannot be used. You need to enable the audio device to use this shortcut, or edit the shortcut to change the audio device.");
|
||||
if (audioDevice.State == AudioSwitcher.AudioApi.DeviceState.NotPresent)
|
||||
return (false, $"The Audio Device {AudioDevice} is not present, so the shortcut '{Name}' cannot be used.");
|
||||
if (audioDevice.State == AudioSwitcher.AudioApi.DeviceState.Unplugged)
|
||||
return (false, $"The Audio Device {AudioDevice} is unplugged, so the shortcut '{Name}' cannot be used. You need to plug in the audio device to use this shortcut, or edit the shortcut to change the audio device.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Do all the specified pre-start apps still exist?
|
||||
|
||||
return (true, "Shortcut is valid");
|
||||
|
||||
@ -1714,143 +1740,6 @@ namespace DisplayMagician
|
||||
|
||||
}
|
||||
|
||||
/*internal class IconActions
|
||||
{
|
||||
// Constants
|
||||
// =========
|
||||
|
||||
private const string Shell32 = "shell32.dll";
|
||||
private const string User32 = "user32.dll";
|
||||
|
||||
// External Methods
|
||||
// ================
|
||||
|
||||
[DllImport(Shell32, CharSet = CharSet.Auto)]
|
||||
private static extern int PickIconDlg(IntPtr hwndOwner, StringBuilder lpstrFile, int nMaxFile, ref int lpdwIconIndex);
|
||||
|
||||
[DllImport(Shell32, CharSet = CharSet.Auto)]
|
||||
private static extern uint ExtractIconEx(string szFileName, int nIconIndex, IntPtr[] phiconLarge, IntPtr[] phiconSmall, uint nIcons);
|
||||
|
||||
[DllImport(User32, CharSet = CharSet.Auto)]
|
||||
private static extern bool DestroyIcon(IntPtr handle);
|
||||
|
||||
// Methods
|
||||
// =======
|
||||
|
||||
public int PickIconDialog(IntPtr hwndOwner, StringBuilder lpstrFile, int nMaxFile, ref int lpdwIconIndex)
|
||||
{
|
||||
return PickIconDlg(hwndOwner, lpstrFile, nMaxFile, ref lpdwIconIndex);
|
||||
}
|
||||
|
||||
public uint ExtractIcon(string szFileName, int nIconIndex, IntPtr[] phiconLarge, IntPtr[] phiconSmall, uint nIcons)
|
||||
{
|
||||
return ExtractIconEx(szFileName, nIconIndex, phiconLarge, phiconSmall, nIcons);
|
||||
}
|
||||
|
||||
public bool DestroyIconAtHandle(IntPtr handle)
|
||||
{
|
||||
return DestroyIcon(handle);
|
||||
}
|
||||
}
|
||||
|
||||
public class IconReference
|
||||
{
|
||||
// Constants
|
||||
// =========
|
||||
|
||||
private const string comma = ",";
|
||||
|
||||
// Variables
|
||||
// =========
|
||||
|
||||
private static readonly Regex regex = new Regex(@".+\,[0-9]+$");
|
||||
|
||||
// Properties
|
||||
// ==========
|
||||
|
||||
/// <summary>
|
||||
/// File path to the icon.
|
||||
/// </summary>
|
||||
public string FilePath { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Index of the icon within the file.
|
||||
/// </summary>
|
||||
public int IconIndex { get; private set; }
|
||||
|
||||
// Constructors
|
||||
// ============
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
/// <param name="reference">A reference for an icon within either an .ico, .exe, or .dll. Must be a valid file location followed by a comma and then an int.</param>
|
||||
/// <exception cref="RegexMatchTimeoutException">Ignore.</exception>
|
||||
public IconReference(string reference)
|
||||
{
|
||||
if (!regex.IsMatch(reference))
|
||||
{
|
||||
throw new ArgumentException("[reference] must be a valid file location followed by a comma and then an int");
|
||||
}
|
||||
|
||||
string[] split = reference.Split(',');
|
||||
string index = split[split.Length - 1];
|
||||
string filePath = reference.Substring(0, reference.Length - index.Length - 1);
|
||||
|
||||
Setup(filePath, index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
/// <param name="filePath">A valid file location for an .ico, .exe, or .dll.</param>
|
||||
/// <param name="index">The index of the icon wanted within the file.</param>
|
||||
public IconReference(string filePath, string index)
|
||||
{
|
||||
Setup(filePath, index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
/// <param name="filePath">A valid file location for an .ico, .exe, or .dll.</param>
|
||||
/// <param name="index">The index of the icon wanted within the file.</param>
|
||||
public IconReference(string filePath, int index)
|
||||
{
|
||||
Setup(filePath, index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the FileName and the IconIndex separated by a comma
|
||||
/// </summary>
|
||||
/// <returns>Returns the FileName and the IconIndex separated by a comma</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return (FilePath ?? string.Empty) + comma + (IconIndex.ToString() ?? string.Empty);
|
||||
}
|
||||
|
||||
private void Setup(string filepath, string index)
|
||||
{
|
||||
if (!int.TryParse(index, out int iconIndex))
|
||||
{
|
||||
throw new ArgumentException("Parameter [index] needs to be castable to an integer");
|
||||
}
|
||||
|
||||
Setup(filepath, iconIndex);
|
||||
}
|
||||
|
||||
private void Setup(string filepath, int index)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
throw new ArgumentException("Parameter [index] needs to be greater than or equal to zero");
|
||||
}
|
||||
|
||||
FilePath = filepath;
|
||||
IconIndex = index;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
#region JsonConverterBitmap
|
||||
internal class CustomBitmapConverter : JsonConverter
|
||||
|
@ -1,4 +1,5 @@
|
||||
using DisplayMagician.GameLibraries;
|
||||
using AudioSwitcher.AudioApi.CoreAudio;
|
||||
using DisplayMagician.GameLibraries;
|
||||
using DisplayMagician.InterProcess;
|
||||
using DisplayMagician.Resources;
|
||||
using DisplayMagician.Shared;
|
||||
@ -31,6 +32,7 @@ namespace DisplayMagician
|
||||
private static string AppShortcutStoragePath = Path.Combine(Program.AppDataPath, $"Shortcuts");
|
||||
private static string _shortcutStorageJsonFileName = Path.Combine(AppShortcutStoragePath, $"Shortcuts_{Version.ToString(2)}.json");
|
||||
private static string uuidV4Regex = @"(?im)^[{(]?[0-9A-F]{8}[-]?(?:[0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?$";
|
||||
private static CoreAudioController _audioController = null;
|
||||
#endregion
|
||||
|
||||
#region Class Constructors
|
||||
@ -40,6 +42,7 @@ namespace DisplayMagician
|
||||
try
|
||||
{
|
||||
NvAPIWrapper.NVIDIA.Initialize();
|
||||
_audioController = new CoreAudioController();
|
||||
|
||||
// Create the Profile Storage Path if it doesn't exist so that it's avilable for all the program
|
||||
if (!Directory.Exists(AppShortcutStoragePath))
|
||||
@ -86,6 +89,14 @@ namespace DisplayMagician
|
||||
}
|
||||
}
|
||||
|
||||
public static CoreAudioController AudioController
|
||||
{
|
||||
get
|
||||
{
|
||||
return _audioController;
|
||||
}
|
||||
}
|
||||
|
||||
public static Version Version
|
||||
{
|
||||
get => new Version(1, 0, 0);
|
||||
@ -118,29 +129,6 @@ namespace DisplayMagician
|
||||
|
||||
}
|
||||
|
||||
/* public static bool ReplaceShortcut(ShortcutItem shortcut)
|
||||
{
|
||||
if (!(shortcut is ShortcutItem))
|
||||
return false;
|
||||
|
||||
// Doublecheck if it already exists
|
||||
// Because then we just update the one that already exists
|
||||
if (ContainsShortcut(shortcut))
|
||||
{
|
||||
// We update the existing Shortcut with the data over
|
||||
ShortcutItem shortcutToUpdate = GetShortcut(shortcut.UUID);
|
||||
shortcutToUpdate = shortcut;
|
||||
// Save the shortcuts JSON as it's different
|
||||
SaveShortcuts();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
}*/
|
||||
|
||||
|
||||
public static bool RemoveShortcut(ShortcutItem shortcut)
|
||||
{
|
||||
if (!(shortcut is ShortcutItem))
|
||||
@ -455,6 +443,24 @@ namespace DisplayMagician
|
||||
}
|
||||
}
|
||||
|
||||
// record the old audio device
|
||||
CoreAudioDevice rollbackAudioDevice = _audioController.DefaultPlaybackDevice;
|
||||
|
||||
// Change Audio Device (if one specified)
|
||||
if (shortcutToUse.ChangeAudioDevice)
|
||||
{
|
||||
IEnumerable<CoreAudioDevice> audioDevices = _audioController.GetPlaybackDevices();
|
||||
foreach (CoreAudioDevice audioDevice in audioDevices)
|
||||
{
|
||||
if (audioDevice.FullName.Equals(shortcutToUse.AudioDevice))
|
||||
{
|
||||
// use the Audio Device
|
||||
audioDevice.SetAsDefault();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the IP Service status back to what it was
|
||||
IPCService.GetInstance().Status = rollbackInstanceStatus;
|
||||
|
||||
@ -665,7 +671,10 @@ namespace DisplayMagician
|
||||
IPCService.GetInstance().Status = InstanceStatus.OnHold;
|
||||
|
||||
// Add a status notification icon in the status area
|
||||
notifyIcon.Text = $"DisplayMagician: Running {steamGameToRun.Name.Substring(0, 41)}...";
|
||||
if (steamGameToRun.Name.Length <= 41)
|
||||
notifyIcon.Text = $"DisplayMagician: Running {steamGameToRun.Name}...";
|
||||
else
|
||||
notifyIcon.Text = $"DisplayMagician: Running {steamGameToRun.Name.Substring(0, 41)}...";
|
||||
Application.DoEvents();
|
||||
|
||||
// Wait 300ms for the game process to spawn
|
||||
@ -815,6 +824,14 @@ namespace DisplayMagician
|
||||
}
|
||||
}
|
||||
|
||||
// Change Audio Device back (if one specified)
|
||||
if (shortcutToUse.ChangeAudioDevice)
|
||||
{
|
||||
// use the Audio Device
|
||||
rollbackAudioDevice.SetAsDefault();
|
||||
}
|
||||
|
||||
|
||||
// Change back to the original profile only if it is different
|
||||
if (needToChangeProfiles)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user