From 3b1980d9e0c5181a90462b7587befdcd899c429d Mon Sep 17 00:00:00 2001 From: Micah Morrison Date: Mon, 13 Mar 2023 07:52:59 -0400 Subject: [PATCH 1/4] Update package for Bluegrams/AppHelpers#7 --- SoundBoard/SoundBoard.csproj | 8 ++++---- SoundBoard/packages.config | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/SoundBoard/SoundBoard.csproj b/SoundBoard/SoundBoard.csproj index 4cad5f7..c65aab0 100644 --- a/SoundBoard/SoundBoard.csproj +++ b/SoundBoard/SoundBoard.csproj @@ -44,8 +44,8 @@ .\icon.ico - - ..\packages\AppHelpers.WPF.0.1.0-rc3\lib\net45\AppHelpers.WPF.dll + + ..\packages\AppHelpers.WPF.0.1.0\lib\net45\AppHelpers.WPF.dll ..\packages\ControlzEx.3.0.2.4\lib\net462\ControlzEx.dll @@ -81,8 +81,8 @@ ..\packages\NAudio.1.9.0\lib\net35\NAudio.dll - - ..\packages\PortableSettingsProvider.0.2.3\lib\net45\PortableSettingsProvider.dll + + ..\packages\PortableSettingsProvider.0.2.4\lib\net45\PortableSettingsProvider.dll diff --git a/SoundBoard/packages.config b/SoundBoard/packages.config index edfa82a..6d68911 100644 --- a/SoundBoard/packages.config +++ b/SoundBoard/packages.config @@ -1,6 +1,6 @@  - + @@ -13,7 +13,7 @@ - + From f06ab03f59a2e6d8a253c6acd9c67736c409283f Mon Sep 17 00:00:00 2001 From: Micah Morrison Date: Mon, 13 Mar 2023 09:24:49 -0400 Subject: [PATCH 2/4] Fix ColorPicker size, use exising colors as starter --- SoundBoard/Buttons.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/SoundBoard/Buttons.cs b/SoundBoard/Buttons.cs index 61c8187..da5645f 100644 --- a/SoundBoard/Buttons.cs +++ b/SoundBoard/Buttons.cs @@ -922,9 +922,24 @@ private void SoundPathMenuItem_Click(object sender, RoutedEventArgs e) Process.Start("explorer.exe", $"/select, \"{SoundPath}\""); } + private static readonly IEnumerable _defaultPalette = (IEnumerable)typeof(ColorPickerDialog) + .GetField("DefaultPalette", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static)? + .GetValue(null) ?? Enumerable.Empty(); + private void SetColorMenuItem_Click(object sender, RoutedEventArgs e) { - ColorPickerDialog colorPickerDialog = new ColorPickerDialog(Color ?? Colors.White) { ShowTransparencyPicker = false }; + var palette = MainWindow.Instance.GetSoundButtons().Where(sb => sb.Color != null).Select(sb => sb.Color.Value) // Existing colors + .Concat(_defaultPalette) // The default palette + .Distinct(); // Remove dupes + + ColorPickerDialog colorPickerDialog = new ColorPickerDialog(Color ?? Colors.White, palette) + { + Width = 584, + Height = 491, + ResizeMode = ResizeMode.NoResize, + WindowStyle = WindowStyle.ToolWindow, + ShowTransparencyPicker = false + }; if (colorPickerDialog.ShowDialog() == true) { From 5db0fffc6743de1e549bdd6e4de45f80b405e2b0 Mon Sep 17 00:00:00 2001 From: Micah Morrison Date: Fri, 14 Apr 2023 12:38:58 -0400 Subject: [PATCH 3/4] Add audio passthrough error handling --- SoundBoard/MainWindow.xaml.cs | 96 ++++++++++++++++----- SoundBoard/Properties/Resources.Designer.cs | 36 ++++++++ SoundBoard/Properties/Resources.resx | 12 +++ 3 files changed, 123 insertions(+), 21 deletions(-) diff --git a/SoundBoard/MainWindow.xaml.cs b/SoundBoard/MainWindow.xaml.cs index 6832065..c7213e9 100644 --- a/SoundBoard/MainWindow.xaml.cs +++ b/SoundBoard/MainWindow.xaml.cs @@ -1576,35 +1576,89 @@ private void HandleInputOutputChange() if (GlobalSettings.GetInputDeviceGuids().Any()) { + Guid inputDeviceId = GlobalSettings.GetInputDeviceGuids().First(); + foreach (var outputDeviceId in GlobalSettings.GetOutputDeviceGuids()) { - // Create the input - Guid inputDeviceId = GlobalSettings.GetInputDeviceGuids().First(); - MMDevice inputDevice = Utilities.GetDevice(inputDeviceId, DataFlow.Capture); - WasapiCapture inputCapture = new WasapiCapture(inputDevice); - inputCapture.RecordingStopped += HandleRecordingStopped; - _inputCaptures.Add(inputCapture); - - // Create the buffer - BufferedWaveProvider bufferedWaveProvider = new BufferedWaveProvider(inputDevice.AudioClient.MixFormat) + try { - DiscardOnBufferOverflow = true - }; - _bufferedWaveProviders.Add(bufferedWaveProvider); + // Create the input + MMDevice inputDevice = Utilities.GetDevice(inputDeviceId, DataFlow.Capture); + WasapiCapture inputCapture = new WasapiCapture(inputDevice); + inputCapture.RecordingStopped += HandleRecordingStopped; + _inputCaptures.Add(inputCapture); + + // Create the buffer + BufferedWaveProvider bufferedWaveProvider = new BufferedWaveProvider(inputDevice.AudioClient.MixFormat) + { + DiscardOnBufferOverflow = true + }; + _bufferedWaveProviders.Add(bufferedWaveProvider); + + inputCapture.DataAvailable += (_, args) => + { + bufferedWaveProvider.AddSamples(args.Buffer, 0, args.BytesRecorded); + }; - inputCapture.DataAvailable += (_, args) => + // Create the outputs + WasapiOut output = new WasapiOut(Utilities.GetDevice(outputDeviceId, DataFlow.Render), AudioClientShareMode.Shared, true, GlobalSettings.AudioPassthroughLatency); + _outputCaptures.Add(output); + + output.Init(bufferedWaveProvider); + output.Play(); + + inputCapture.StartRecording(); + } + catch (Exception ex) { - bufferedWaveProvider.AddSamples(args.Buffer, 0, args.BytesRecorded); - }; + HandleRecordingStopped(this, new StoppedEventArgs()); - // Create the outputs - WasapiOut output = new WasapiOut(Utilities.GetDevice(outputDeviceId, DataFlow.Render), AudioClientShareMode.Shared, true, GlobalSettings.AudioPassthroughLatency); - _outputCaptures.Add(output); + Dispatcher.Invoke(async () => + { + // Try to get the friendly input/output device names. + string inputDeviceName = Properties.Resources.UNKNOWN; + string outputDeviceName = Properties.Resources.UNKNOWN; + try + { + inputDeviceName = Utilities.GetDevice(inputDeviceId, DataFlow.Capture).FriendlyName; + } + catch {} + try + { + outputDeviceName = Utilities.GetDevice(outputDeviceId, DataFlow.Render).FriendlyName; + } + catch {} + + string error = string.Format(Properties.Resources.AudioPassthroughError, inputDeviceName, outputDeviceName); + + if (ex is COMException comException) + { + if (comException.ErrorCode == -2004287478) + { + // This is a specific error we know about which means the output device is being held exclusively. + error += $"{Environment.NewLine}{Environment.NewLine}{Properties.Resources.AudioPassthroughOutputExclusiveError}"; + } + + error += $"{Environment.NewLine}{Environment.NewLine}{string.Format(Properties.Resources.ComErrorCode, comException.ErrorCode)}"; + } - output.Init(bufferedWaveProvider); - output.Play(); + string fullError = $"{error}{Environment.NewLine}{Environment.NewLine}{ex}"; - inputCapture.StartRecording(); + var res = await this.ShowMessageAsync(Properties.Resources.Error, error, + MessageDialogStyle.AffirmativeAndNegative, new MetroDialogSettings + { + AffirmativeButtonText = Properties.Resources.CopyDetails, + NegativeButtonText = Properties.Resources.OK + }); + + if (res == MessageDialogResult.Affirmative) + { + Clipboard.SetText(fullError); + } + }); + + return; + } } } } diff --git a/SoundBoard/Properties/Resources.Designer.cs b/SoundBoard/Properties/Resources.Designer.cs index 97bdda5..2711d1a 100644 --- a/SoundBoard/Properties/Resources.Designer.cs +++ b/SoundBoard/Properties/Resources.Designer.cs @@ -87,6 +87,24 @@ internal static string AllSoundsClearedFromTab { } } + /// + /// Looks up a localized string similar to There was an error opening the input ({0}) or output ({1}) audio device for audio passthrough.. + /// + internal static string AudioPassthroughError { + get { + return ResourceManager.GetString("AudioPassthroughError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The output audio device is being used exclusively by another application.. + /// + internal static string AudioPassthroughOutputExclusiveError { + get { + return ResourceManager.GetString("AudioPassthroughOutputExclusiveError", resourceCulture); + } + } + /// /// Looks up a localized string similar to Audio and Video Files. /// @@ -186,6 +204,15 @@ internal static string Close { } } + /// + /// Looks up a localized string similar to Error code: 0x{0:X}. + /// + internal static string ComErrorCode { + get { + return ResourceManager.GetString("ComErrorCode", resourceCulture); + } + } + /// /// Looks up a localized string similar to There was an error loading the SoundBoard configuration. A backup has been made at '{0}'. /// @@ -756,6 +783,15 @@ internal static string UnexpectedError { } } + /// + /// Looks up a localized string similar to UNKNOWN. + /// + internal static string UNKNOWN { + get { + return ResourceManager.GetString("UNKNOWN", resourceCulture); + } + } + /// /// Looks up a localized string similar to Version {0}. /// diff --git a/SoundBoard/Properties/Resources.resx b/SoundBoard/Properties/Resources.resx index 0c42fbf..07151fb 100644 --- a/SoundBoard/Properties/Resources.resx +++ b/SoundBoard/Properties/Resources.resx @@ -380,4 +380,16 @@ Global Hotkey: {1} Change Default Button Grid + + UNKNOWN + + + There was an error opening the input ({0}) or output ({1}) audio device for audio passthrough. + + + Error code: 0x{0:X} + + + The output audio device is being used exclusively by another application. + \ No newline at end of file From a277f5686f8f9f05d632a7a34aaa14fb646c2003 Mon Sep 17 00:00:00 2001 From: Micah Morrison Date: Fri, 14 Apr 2023 12:41:26 -0400 Subject: [PATCH 4/4] Bump version to 1.10.1 --- SoundBoard/Properties/AssemblyInfo.cs | 4 ++-- SoundBoard/VersionInfo.xml | 20 ++++++-------------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/SoundBoard/Properties/AssemblyInfo.cs b/SoundBoard/Properties/AssemblyInfo.cs index 8f7a60d..458735a 100644 --- a/SoundBoard/Properties/AssemblyInfo.cs +++ b/SoundBoard/Properties/AssemblyInfo.cs @@ -51,5 +51,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.10.0.2")] -[assembly: AssemblyFileVersion("1.10.0.2")] +[assembly: AssemblyVersion("1.10.1.0")] +[assembly: AssemblyFileVersion("1.10.1.0")] diff --git a/SoundBoard/VersionInfo.xml b/SoundBoard/VersionInfo.xml index 872443f..85ee823 100644 --- a/SoundBoard/VersionInfo.xml +++ b/SoundBoard/VersionInfo.xml @@ -1,29 +1,21 @@ - 1.10.0.2 - 2023-03-10 + 1.10.1.0 + 2023-04-14 - https://github.com/micahmo/SoundBoard/releases/download/v1.10.0/SoundBoard.exe + https://github.com/micahmo/SoundBoard/releases/download/v1.10.1/SoundBoard.exe SoundBoard.exe - https://github.com/micahmo/SoundBoard/releases/download/v1.10.0/SoundBoard.exe + https://github.com/micahmo/SoundBoard/releases/download/v1.10.1/SoundBoard.exe SoundBoard.exe - - Audio recording device can be passed through to an audio playback device (#18) - - Hotkeys can be assigned to sounds - - Multiple sounds or a whole folder can be added at once - - Select sounds with Control- or Shift-Click to update or play multiple at once - - Sounds can be configured to stop all other sounds when played - - Sound names are more readable at different sizes (#17) - - Tabs with currently playing sounds will now be clearly indicated - - Sounds can trigger other sounds, allowing chaining - - The default grid layout for new pages can be configured - - General bug fixes and improvements + - Improve color picker + - Handle audio passthrough errors \ No newline at end of file