From 9a60f84ff61f98784d445e60437ac7778f9f0e83 Mon Sep 17 00:00:00 2001 From: CasualPokePlayer <50538166+CasualPokePlayer@users.noreply.github.com> Date: Sun, 5 May 2024 17:52:44 -0700 Subject: [PATCH] Remove DirectSound support This has been the source of various reported odd issues/crashes due to buggy DirectSound drivers. DirectSound is just deprecated anyways, and the code handling it is very fragile and filled with hacks. XAudio2 would be preferred in practically any case (not to mention XAudio2 is built-in for modern Windows versions, with some redist version available for older Windows versions). OpenAL works fine as a substitute in case XAudio2 isn't available. --- .../BizHawk.Bizware.Audio.csproj | 1 - .../DirectSoundSoundOutput.cs | 380 ------------------ .../XAudio2SoundOutput.cs | 3 +- .../HostCapabilityDetector.cs | 33 +- src/BizHawk.Client.Common/config/Config.cs | 4 +- .../config/ConfigEnums.cs | 5 +- src/BizHawk.Client.EmuHawk/MainForm.Events.cs | 3 +- src/BizHawk.Client.EmuHawk/MainForm.cs | 10 +- src/BizHawk.Client.EmuHawk/Sound/Sound.cs | 10 +- .../config/DisplayConfig.cs | 2 +- .../config/SoundConfig.Designer.cs | 60 +-- .../config/SoundConfig.cs | 9 +- 12 files changed, 59 insertions(+), 461 deletions(-) delete mode 100644 src/BizHawk.Bizware.Audio/DirectSoundSoundOutput.cs diff --git a/src/BizHawk.Bizware.Audio/BizHawk.Bizware.Audio.csproj b/src/BizHawk.Bizware.Audio/BizHawk.Bizware.Audio.csproj index a1c9b5e257..c14d2abf4c 100644 --- a/src/BizHawk.Bizware.Audio/BizHawk.Bizware.Audio.csproj +++ b/src/BizHawk.Bizware.Audio/BizHawk.Bizware.Audio.csproj @@ -14,7 +14,6 @@ - diff --git a/src/BizHawk.Bizware.Audio/DirectSoundSoundOutput.cs b/src/BizHawk.Bizware.Audio/DirectSoundSoundOutput.cs deleted file mode 100644 index ac2303d9f9..0000000000 --- a/src/BizHawk.Bizware.Audio/DirectSoundSoundOutput.cs +++ /dev/null @@ -1,380 +0,0 @@ -using System; -using System.Buffers; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Threading; - -using BizHawk.Client.Common; -using BizHawk.Common; - -using SharpDX; -using SharpDX.DirectSound; -using SharpDX.Multimedia; - -namespace BizHawk.Bizware.Audio -{ - public sealed class DirectSoundSoundOutput : ISoundOutput - { - private readonly IHostAudioManager _sound; - private readonly IntPtr _mainWindowHandle; - private bool _disposed; - private DirectSound _device; - private SecondarySoundBuffer _deviceBuffer, _wavDeviceBuffer; - private int _actualWriteOffsetBytes = -1; - private int _filledBufferSizeBytes; - private long _lastWriteTime; - private int _lastWriteCursor; - private int _retryCounter; - - public DirectSoundSoundOutput(IHostAudioManager sound, IntPtr mainWindowHandle, string soundDevice) - { - _sound = sound; - _mainWindowHandle = mainWindowHandle; // needed for resetting _device on device invalidation - _retryCounter = 5; - - var deviceInfo = DirectSound.GetDevices().Find(d => d.Description == soundDevice); - _device = deviceInfo != null ? new(deviceInfo.DriverGuid) : new(); - _device.SetCooperativeLevel(mainWindowHandle, CooperativeLevel.Priority); - } - - public void Dispose() - { - if (_disposed) return; - - StopWav(throwOnInvalidDevice: false); - _device.Dispose(); - _device = null; - - _disposed = true; - } - - public static IEnumerable GetDeviceNames() - { - return DirectSound.GetDevices().Select(d => d.Description); - } - - private int BufferSizeSamples { get; set; } - - private int BufferSizeBytes => BufferSizeSamples * _sound.BlockAlign; - - public int MaxSamplesDeficit { get; private set; } - - private void ResetToDefaultDevice() - { - // can't use StopSound, as that checks IsPlaying, which will end up calling this function again! - _deviceBuffer.Dispose(); - _deviceBuffer = null; - - StopWav(throwOnInvalidDevice: false); - - _device.Dispose(); - _device = new(); - _device.SetCooperativeLevel(_mainWindowHandle, CooperativeLevel.Priority); - - StartPlaying(); - } - - private bool IsPlaying - { - get - { - if (_deviceBuffer == null) - { - return false; - } - - try - { - var status = (BufferStatus)_deviceBuffer.Status; - return (status & (BufferStatus.BufferLost | BufferStatus.Playing)) is BufferStatus.Playing; - } - catch (SharpDXException) - { - // this only seems to ever occur if the device is disconnected... - ResetToDefaultDevice(); - return false; - } - } - } - - private void StartPlaying() - { - _actualWriteOffsetBytes = -1; - _filledBufferSizeBytes = 0; - _lastWriteTime = 0; - _lastWriteCursor = 0; - var attempts = _retryCounter; - while (!IsPlaying && attempts > 0) - { - attempts--; - try - { - if (_deviceBuffer == null) - { - var format = WaveFormat.CreateCustomFormat( - tag: WaveFormatEncoding.Pcm, - sampleRate: _sound.SampleRate, - channels: _sound.ChannelCount, - averageBytesPerSecond: _sound.SampleRate * _sound.BlockAlign, - blockAlign: _sound.BlockAlign, - bitsPerSample: _sound.BytesPerSample * 8); - - var desc = new SoundBufferDescription - { - Format = format, - Flags = - BufferFlags.GlobalFocus | - BufferFlags.Software | - BufferFlags.GetCurrentPosition2 | - BufferFlags.ControlVolume, - BufferBytes = BufferSizeBytes - }; - - _deviceBuffer = new(_device, desc); - } - - _deviceBuffer.Play(0, PlayFlags.Looping); - } - catch (SharpDXException) - { - _deviceBuffer?.Restore(); - if (attempts > 0) - { - Thread.Sleep(10); - } - } - } - - if (IsPlaying) - { - _retryCounter = 5; - } - else if (_retryCounter > 1) - { - _retryCounter--; - } - } - - public void ApplyVolumeSettings(double volume) - { - if (IsPlaying) - { - try - { - // I'm not sure if this is "technically" correct but it works okay - const int range = Volume.Maximum - Volume.Minimum; - _deviceBuffer.Volume = (int)(Math.Pow(volume, 0.1) * range) + Volume.Minimum; - } - catch (SharpDXException) - { - } - } - } - - public void StartSound() - { - BufferSizeSamples = _sound.MillisecondsToSamples(_sound.ConfigBufferSizeMs); - - // 35 to 65 milliseconds depending on how big the buffer is. This is a trade-off - // between more frequent but less severe glitches (i.e. catching underruns before - // they happen and filling the buffer with silence) or less frequent but more - // severe glitches. At least on my Windows 8 machines, the distance between the - // play and write cursors can be up to 30 milliseconds, so that would be the - // absolute minimum we could use here. - var minBufferFullnessMs = Math.Min(35 + (_sound.ConfigBufferSizeMs - 60) / 2, 65); - MaxSamplesDeficit = BufferSizeSamples - _sound.MillisecondsToSamples(minBufferFullnessMs); - - StartPlaying(); - } - - public void StopSound() - { - if (IsPlaying) - { - try - { - _deviceBuffer.Stop(); - } - catch (SharpDXException) - { - } - } - - _deviceBuffer.Dispose(); - _deviceBuffer = null; - BufferSizeSamples = 0; - } - - public int CalculateSamplesNeeded() - { - var samplesNeeded = 0; - if (IsPlaying) - { - try - { - var currentWriteTime = Stopwatch.GetTimestamp(); - _deviceBuffer.GetCurrentPosition(out var playCursor, out var writeCursor); - var isInitializing = _actualWriteOffsetBytes == -1; - var detectedUnderrun = false; - if (!isInitializing) - { - var elapsedSeconds = (currentWriteTime - _lastWriteTime) / (double)Stopwatch.Frequency; - var bufferSizeSeconds = (double) BufferSizeSamples / _sound.SampleRate; - var cursorDelta = CircularDistance(_lastWriteCursor, writeCursor, BufferSizeBytes); - cursorDelta += BufferSizeBytes * (int) Math.Round((elapsedSeconds - (cursorDelta / (double) (_sound.SampleRate * _sound.BlockAlign))) / bufferSizeSeconds); - _filledBufferSizeBytes -= cursorDelta; - detectedUnderrun = _filledBufferSizeBytes < 0; - } - if (isInitializing || detectedUnderrun) - { - _actualWriteOffsetBytes = writeCursor; - _filledBufferSizeBytes = 0; - } - samplesNeeded = CircularDistance(_actualWriteOffsetBytes, playCursor, BufferSizeBytes) / _sound.BlockAlign; - if (isInitializing || detectedUnderrun) - { - _sound.HandleInitializationOrUnderrun(detectedUnderrun, ref samplesNeeded); - } - _lastWriteTime = currentWriteTime; - _lastWriteCursor = writeCursor; - } - catch (SharpDXException) - { - samplesNeeded = 0; - } - } - return samplesNeeded; - } - - private static int CircularDistance(int start, int end, int size) - { - return (end - start + size) % size; - } - - public void WriteSamples(short[] samples, int sampleOffset, int sampleCount) - { - // For lack of a better place, this function will be the one that attempts to restart playing - // after a sound buffer is lost. - if (IsPlaying) - { - if (sampleCount == 0) return; - try - { - _deviceBuffer.Write(samples, sampleOffset * _sound.ChannelCount, sampleCount * _sound.ChannelCount, _actualWriteOffsetBytes, LockFlags.None); - _actualWriteOffsetBytes = (_actualWriteOffsetBytes + (sampleCount * _sound.BlockAlign)) % BufferSizeBytes; - _filledBufferSizeBytes += sampleCount * _sound.BlockAlign; - } - catch (SharpDXException) - { - _deviceBuffer.Restore(); - StartPlaying(); - } - } - else - { - _deviceBuffer?.Restore(); - StartPlaying(); - } - } - - private bool IsWavPlaying - { - get - { - if (_wavDeviceBuffer == null) - { - return false; - } - - var status = (BufferStatus)_wavDeviceBuffer.Status; - return (status & (BufferStatus.BufferLost | BufferStatus.Playing)) is BufferStatus.Playing; - } - } - - private void StopWav(bool throwOnInvalidDevice = true) - { - bool isPlaying; - try - { - isPlaying = IsWavPlaying; - } - catch (SharpDXException) - { - if (throwOnInvalidDevice) - { - throw; - } - - isPlaying = false; - } - - if (isPlaying) - { - try - { - _wavDeviceBuffer.Stop(); - } - catch (SharpDXException) - { - } - } - - _wavDeviceBuffer?.Dispose(); - _wavDeviceBuffer = null; - } - - public void PlayWavFile(Stream wavFile, double volume) - { - using var wavStream = new SDL2WavStream(wavFile); - var format = wavStream.Format == SDL2WavStream.AudioFormat.F32LSB - ? WaveFormat.CreateIeeeFloatWaveFormat(wavStream.Frequency, wavStream.Channels) - : new(wavStream.Frequency, wavStream.BitsPerSample, wavStream.Channels); - - var desc = new SoundBufferDescription - { - Format = format, - Flags = - BufferFlags.GlobalFocus | - BufferFlags.Software | - BufferFlags.GetCurrentPosition2 | - BufferFlags.ControlVolume, - BufferBytes = unchecked((int)wavStream.Length) - }; - - StopWav(); - _wavDeviceBuffer = new(_device, desc); - const int TEMP_BUFFER_LENGTH = 65536; - var tempBuffer = ArrayPool.Shared.Rent(TEMP_BUFFER_LENGTH); - try - { - var bufferOffset = 0; - while (true) - { - var numRead = wavStream.Read(tempBuffer, 0, TEMP_BUFFER_LENGTH); - if (numRead == 0) - { - break; - } - - if (wavStream.Format == SDL2WavStream.AudioFormat.S16MSB) - { - EndiannessUtils.MutatingByteSwap16(tempBuffer.AsSpan()[..numRead]); - } - - _wavDeviceBuffer.Write(tempBuffer, 0, numRead, bufferOffset, LockFlags.None); - bufferOffset += numRead; - } - } - finally - { - ArrayPool.Shared.Return(tempBuffer); - } - - const int range = Volume.Maximum - Volume.Minimum; - _wavDeviceBuffer.Volume = (int)(Math.Pow(volume, 0.1) * range) + Volume.Minimum; - _wavDeviceBuffer.Play(0, PlayFlags.None); - } - } -} diff --git a/src/BizHawk.Bizware.Audio/XAudio2SoundOutput.cs b/src/BizHawk.Bizware.Audio/XAudio2SoundOutput.cs index 59412b62a3..8fa73d506d 100644 --- a/src/BizHawk.Bizware.Audio/XAudio2SoundOutput.cs +++ b/src/BizHawk.Bizware.Audio/XAudio2SoundOutput.cs @@ -114,13 +114,12 @@ namespace BizHawk.Bizware.Audio { if (_deviceResetRequired) { - _deviceResetRequired = false; - StopSound(); StopWav(); _masteringVoice.Dispose(); _device.Dispose(); + _deviceResetRequired = false; _device = XAudio2.XAudio2Create(); _device.CriticalError += (_, _) => _deviceResetRequired = true; _masteringVoice = _device.CreateMasteringVoice( diff --git a/src/BizHawk.Client.Common/HostCapabilityDetector.cs b/src/BizHawk.Client.Common/HostCapabilityDetector.cs index b7f97e7600..feb4914c49 100644 --- a/src/BizHawk.Client.Common/HostCapabilityDetector.cs +++ b/src/BizHawk.Client.Common/HostCapabilityDetector.cs @@ -6,17 +6,38 @@ namespace BizHawk.Client.Common { public static class HostCapabilityDetector { - private static bool? _hasDirectX = null; - - public static bool HasDirectX => _hasDirectX ??= DetectDirectX(); - - private static bool DetectDirectX() + private static readonly Lazy _hasD3D9 = new(() => { if (OSTailoredCode.IsUnixHost) return false; var p = OSTailoredCode.LinkedLibManager.LoadOrZero("d3dx9_43.dll"); if (p == IntPtr.Zero) return false; OSTailoredCode.LinkedLibManager.FreeByPtr(p); return true; - } + }); + + private static readonly Lazy _hasXAudio2 = new(() => + { + if (OSTailoredCode.IsUnixHost) + { + return false; + } + + // This should always work for anything Windows 8+ (where XAudio 2.8/2.9 is built-in) + var libNames = new[] { "xaudio2_9.dll", "xaudio2_8.dll", "xaudio2_9redist.dll" }; + foreach (var libName in libNames) + { + var p = OSTailoredCode.LinkedLibManager.LoadOrZero(libName); + if (p != IntPtr.Zero) + { + OSTailoredCode.LinkedLibManager.FreeByPtr(p); + return true; + } + } + + return false; + }); + + public static bool HasD3D9 => _hasD3D9.Value; + public static bool HasXAudio2 => _hasXAudio2.Value; } } diff --git a/src/BizHawk.Client.Common/config/Config.cs b/src/BizHawk.Client.Common/config/Config.cs index 0589440f49..5df041be6f 100644 --- a/src/BizHawk.Client.Common/config/Config.cs +++ b/src/BizHawk.Client.Common/config/Config.cs @@ -220,7 +220,7 @@ namespace BizHawk.Client.Common public int DispPrescale { get; set; } = 1; - public EDispMethod DispMethod { get; set; } = HostCapabilityDetector.HasDirectX && !OSTailoredCode.IsWine ? EDispMethod.D3D9 : EDispMethod.OpenGL; + public EDispMethod DispMethod { get; set; } = HostCapabilityDetector.HasD3D9 && !OSTailoredCode.IsWine ? EDispMethod.D3D9 : EDispMethod.OpenGL; public int DispChromeFrameWindowed { get; set; } = 2; public bool DispChromeStatusBarWindowed { get; set; } = true; @@ -248,7 +248,7 @@ namespace BizHawk.Client.Common public int DispCropBottom { get; set; } = 0; // Sound options - public ESoundOutputMethod SoundOutputMethod { get; set; } = HostCapabilityDetector.HasDirectX ? ESoundOutputMethod.DirectSound : ESoundOutputMethod.OpenAL; + public ESoundOutputMethod SoundOutputMethod { get; set; } = HostCapabilityDetector.HasXAudio2 ? ESoundOutputMethod.XAudio2 : ESoundOutputMethod.OpenAL; /// iff , cores may skip processing audio /// diff --git a/src/BizHawk.Client.Common/config/ConfigEnums.cs b/src/BizHawk.Client.Common/config/ConfigEnums.cs index efe3d9aa1e..12ecaa8968 100644 --- a/src/BizHawk.Client.Common/config/ConfigEnums.cs +++ b/src/BizHawk.Client.Common/config/ConfigEnums.cs @@ -2,7 +2,10 @@ { public enum ESoundOutputMethod { - DirectSound, XAudio2, OpenAL, Dummy + LegacyDirectSound, // kept here to handle old configs + XAudio2, + OpenAL, + Dummy } public enum EDispManagerAR diff --git a/src/BizHawk.Client.EmuHawk/MainForm.Events.cs b/src/BizHawk.Client.EmuHawk/MainForm.Events.cs index af71ec51f9..3d394ba46a 100644 --- a/src/BizHawk.Client.EmuHawk/MainForm.Events.cs +++ b/src/BizHawk.Client.EmuHawk/MainForm.Events.cs @@ -885,7 +885,6 @@ namespace BizHawk.Client.EmuHawk { static IEnumerable GetDeviceNamesCallback(ESoundOutputMethod outputMethod) => outputMethod switch { - ESoundOutputMethod.DirectSound => DirectSoundSoundOutput.GetDeviceNames(), ESoundOutputMethod.XAudio2 => XAudio2SoundOutput.GetDeviceNames(), ESoundOutputMethod.OpenAL => OpenALSoundOutput.GetDeviceNames(), _ => Enumerable.Empty() @@ -903,7 +902,7 @@ namespace BizHawk.Client.EmuHawk else { Sound.Dispose(); - Sound = new Sound(Handle, Config, () => Emulator.VsyncRate()); + Sound = new Sound(Config, () => Emulator.VsyncRate()); } Sound.StartSound(); RewireSound(); diff --git a/src/BizHawk.Client.EmuHawk/MainForm.cs b/src/BizHawk.Client.EmuHawk/MainForm.cs index d419410dd0..e610bf9c70 100644 --- a/src/BizHawk.Client.EmuHawk/MainForm.cs +++ b/src/BizHawk.Client.EmuHawk/MainForm.cs @@ -595,10 +595,10 @@ namespace BizHawk.Client.EmuHawk InputManager.ResetMainControllers(_autofireNullControls); InputManager.AutofireStickyXorAdapter.SetOnOffPatternFromConfig(Config.AutofireOn, Config.AutofireOff); var savedOutputMethod = Config.SoundOutputMethod; - if (savedOutputMethod is ESoundOutputMethod.Dummy) Config.SoundOutputMethod = HostCapabilityDetector.HasDirectX ? ESoundOutputMethod.DirectSound : ESoundOutputMethod.OpenAL; + if (savedOutputMethod is ESoundOutputMethod.Dummy) Config.SoundOutputMethod = HostCapabilityDetector.HasXAudio2 ? ESoundOutputMethod.XAudio2 : ESoundOutputMethod.OpenAL; try { - Sound = new Sound(Handle, Config, () => Emulator.VsyncRate()); + Sound = new Sound(Config, () => Emulator.VsyncRate()); } catch { @@ -606,14 +606,12 @@ namespace BizHawk.Client.EmuHawk { ShowMessageBox( owner: null, - text: savedOutputMethod is ESoundOutputMethod.DirectSound - ? "Couldn't initialize DirectSound! Things may go poorly for you. Try changing your sound driver to 44.1khz instead of 48khz in mmsys.cpl." - : "Couldn't initialize sound device! Try changing the output method in Sound config.", + text: "Couldn't initialize sound device! Try changing the output method in Sound config.", caption: "Initialization Error", EMsgBoxIcon.Error); } Config.SoundOutputMethod = ESoundOutputMethod.Dummy; - Sound = new Sound(Handle, Config, () => Emulator.VsyncRate()); + Sound = new Sound(Config, () => Emulator.VsyncRate()); } Sound.StartSound(); diff --git a/src/BizHawk.Client.EmuHawk/Sound/Sound.cs b/src/BizHawk.Client.EmuHawk/Sound/Sound.cs index fe4886b531..0ba3efc41d 100644 --- a/src/BizHawk.Client.EmuHawk/Sound/Sound.cs +++ b/src/BizHawk.Client.EmuHawk/Sound/Sound.cs @@ -32,7 +32,7 @@ namespace BizHawk.Client.EmuHawk public int ConfigBufferSizeMs => Config.SoundBufferSizeMs; - public Sound(IntPtr mainWindowHandle, Config config, Func getCoreVsyncRateCallback) + public Sound(Config config, Func getCoreVsyncRateCallback) { BlockAlign = BytesPerSample * ChannelCount; @@ -40,9 +40,14 @@ namespace BizHawk.Client.EmuHawk _outputProvider = new SoundOutputProvider(_getCoreVsyncRateCallback); Config = config; + if (config.SoundOutputMethod == ESoundOutputMethod.LegacyDirectSound) + { + config.SoundOutputMethod = HostCapabilityDetector.HasXAudio2 ? ESoundOutputMethod.XAudio2 : ESoundOutputMethod.OpenAL; + } + if (OSTailoredCode.IsUnixHost) { - // if DirectSound or XAudio is chosen, use OpenAL, otherwise comply with the user's choice + // if XAudio is chosen, use OpenAL, otherwise comply with the user's choice _outputDevice = config.SoundOutputMethod == ESoundOutputMethod.Dummy ? new DummySoundOutput(this) : new OpenALSoundOutput(this, config.SoundDevice); @@ -51,7 +56,6 @@ namespace BizHawk.Client.EmuHawk { _outputDevice = config.SoundOutputMethod switch { - ESoundOutputMethod.DirectSound => new DirectSoundSoundOutput(this, mainWindowHandle, config.SoundDevice), ESoundOutputMethod.XAudio2 => new XAudio2SoundOutput(this, config.SoundDevice), ESoundOutputMethod.OpenAL => new OpenALSoundOutput(this, config.SoundDevice), _ => new DummySoundOutput(this) diff --git a/src/BizHawk.Client.EmuHawk/config/DisplayConfig.cs b/src/BizHawk.Client.EmuHawk/config/DisplayConfig.cs index 556b574dab..cf25fcd905 100755 --- a/src/BizHawk.Client.EmuHawk/config/DisplayConfig.cs +++ b/src/BizHawk.Client.EmuHawk/config/DisplayConfig.cs @@ -110,7 +110,7 @@ namespace BizHawk.Client.EmuHawk RefreshAspectRatioOptions(); - if (!HostCapabilityDetector.HasDirectX) + if (!HostCapabilityDetector.HasD3D9) { rbD3D9.Enabled = false; rbD3D9.AutoCheck = false; diff --git a/src/BizHawk.Client.EmuHawk/config/SoundConfig.Designer.cs b/src/BizHawk.Client.EmuHawk/config/SoundConfig.Designer.cs index fc60c8a5a5..370031995d 100644 --- a/src/BizHawk.Client.EmuHawk/config/SoundConfig.Designer.cs +++ b/src/BizHawk.Client.EmuHawk/config/SoundConfig.Designer.cs @@ -47,7 +47,6 @@ this.grpOutputMethod = new System.Windows.Forms.GroupBox(); this.rbOutputMethodOpenAL = new System.Windows.Forms.RadioButton(); this.rbOutputMethodXAudio2 = new System.Windows.Forms.RadioButton(); - this.rbOutputMethodDirectSound = new System.Windows.Forms.RadioButton(); this.cbMuteFrameAdvance = new System.Windows.Forms.CheckBox(); this.cbEnableMaster = new System.Windows.Forms.CheckBox(); this.label3 = new BizHawk.WinForms.Controls.LocLabelEx(); @@ -117,11 +116,7 @@ this.nudRWFF.Name = "nudRWFF"; this.nudRWFF.Size = new System.Drawing.Size(45, 20); this.nudRWFF.TabIndex = 7; - this.nudRWFF.Value = new decimal(new int[] { - 100, - 0, - 0, - 0}); + this.nudRWFF.Value = new decimal(new int[] { 100, 0, 0, 0 }); this.nudRWFF.ValueChanged += new System.EventHandler(this.nudRWFF_ValueChanged); // // cbEnableRWFF @@ -141,7 +136,7 @@ this.tbRWFF.Maximum = 100; this.tbRWFF.Name = "tbRWFF"; this.tbRWFF.Orientation = System.Windows.Forms.Orientation.Vertical; - this.tbRWFF.Size = new System.Drawing.Size(42, 164); + this.tbRWFF.Size = new System.Drawing.Size(45, 164); this.tbRWFF.TabIndex = 6; this.tbRWFF.TickFrequency = 10; this.tbRWFF.Scroll += new System.EventHandler(this.TbRwff_Scroll); @@ -167,7 +162,7 @@ this.tbNormal.Maximum = 100; this.tbNormal.Name = "tbNormal"; this.tbNormal.Orientation = System.Windows.Forms.Orientation.Vertical; - this.tbNormal.Size = new System.Drawing.Size(42, 164); + this.tbNormal.Size = new System.Drawing.Size(45, 164); this.tbNormal.TabIndex = 2; this.tbNormal.TickFrequency = 10; this.tbNormal.Scroll += new System.EventHandler(this.TrackBar1_Scroll); @@ -178,18 +173,12 @@ this.nudNormal.Name = "nudNormal"; this.nudNormal.Size = new System.Drawing.Size(45, 20); this.nudNormal.TabIndex = 3; - this.nudNormal.Value = new decimal(new int[] { - 100, - 0, - 0, - 0}); + this.nudNormal.Value = new decimal(new int[] { 100, 0, 0, 0 }); this.nudNormal.ValueChanged += new System.EventHandler(this.SoundVolNumeric_ValueChanged); // // listBoxSoundDevices // - this.listBoxSoundDevices.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.listBoxSoundDevices.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.listBoxSoundDevices.FormattingEnabled = true; this.listBoxSoundDevices.Location = new System.Drawing.Point(138, 110); this.listBoxSoundDevices.Name = "listBoxSoundDevices"; @@ -213,24 +202,12 @@ // this.BufferSizeNumeric.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.BufferSizeNumeric.Location = new System.Drawing.Point(202, 208); - this.BufferSizeNumeric.Maximum = new decimal(new int[] { - 250, - 0, - 0, - 0}); - this.BufferSizeNumeric.Minimum = new decimal(new int[] { - 30, - 0, - 0, - 0}); + this.BufferSizeNumeric.Maximum = new decimal(new int[] { 250, 0, 0, 0 }); + this.BufferSizeNumeric.Minimum = new decimal(new int[] { 30, 0, 0, 0 }); this.BufferSizeNumeric.Name = "BufferSizeNumeric"; this.BufferSizeNumeric.Size = new System.Drawing.Size(59, 20); this.BufferSizeNumeric.TabIndex = 10; - this.BufferSizeNumeric.Value = new decimal(new int[] { - 100, - 0, - 0, - 0}); + this.BufferSizeNumeric.Value = new decimal(new int[] { 100, 0, 0, 0 }); // // BufferSizeUnitsLabel // @@ -243,10 +220,9 @@ // this.grpOutputMethod.Controls.Add(this.rbOutputMethodOpenAL); this.grpOutputMethod.Controls.Add(this.rbOutputMethodXAudio2); - this.grpOutputMethod.Controls.Add(this.rbOutputMethodDirectSound); this.grpOutputMethod.Location = new System.Drawing.Point(292, 12); this.grpOutputMethod.Name = "grpOutputMethod"; - this.grpOutputMethod.Size = new System.Drawing.Size(100, 90); + this.grpOutputMethod.Size = new System.Drawing.Size(100, 73); this.grpOutputMethod.TabIndex = 12; this.grpOutputMethod.TabStop = false; this.grpOutputMethod.Text = "Output Method"; @@ -254,7 +230,7 @@ // rbOutputMethodOpenAL // this.rbOutputMethodOpenAL.AutoSize = true; - this.rbOutputMethodOpenAL.Location = new System.Drawing.Point(6, 65); + this.rbOutputMethodOpenAL.Location = new System.Drawing.Point(6, 43); this.rbOutputMethodOpenAL.Name = "rbOutputMethodOpenAL"; this.rbOutputMethodOpenAL.Size = new System.Drawing.Size(64, 17); this.rbOutputMethodOpenAL.TabIndex = 2; @@ -266,7 +242,7 @@ // rbOutputMethodXAudio2 // this.rbOutputMethodXAudio2.AutoSize = true; - this.rbOutputMethodXAudio2.Location = new System.Drawing.Point(6, 42); + this.rbOutputMethodXAudio2.Location = new System.Drawing.Point(6, 20); this.rbOutputMethodXAudio2.Name = "rbOutputMethodXAudio2"; this.rbOutputMethodXAudio2.Size = new System.Drawing.Size(65, 17); this.rbOutputMethodXAudio2.TabIndex = 1; @@ -275,18 +251,6 @@ this.rbOutputMethodXAudio2.UseVisualStyleBackColor = true; this.rbOutputMethodXAudio2.CheckedChanged += new System.EventHandler(this.OutputMethodRadioButtons_CheckedChanged); // - // rbOutputMethodDirectSound - // - this.rbOutputMethodDirectSound.AutoSize = true; - this.rbOutputMethodDirectSound.Location = new System.Drawing.Point(6, 19); - this.rbOutputMethodDirectSound.Name = "rbOutputMethodDirectSound"; - this.rbOutputMethodDirectSound.Size = new System.Drawing.Size(84, 17); - this.rbOutputMethodDirectSound.TabIndex = 0; - this.rbOutputMethodDirectSound.TabStop = true; - this.rbOutputMethodDirectSound.Text = "DirectSound"; - this.rbOutputMethodDirectSound.UseVisualStyleBackColor = true; - this.rbOutputMethodDirectSound.CheckedChanged += new System.EventHandler(this.OutputMethodRadioButtons_CheckedChanged); - // // cbMuteFrameAdvance // this.cbMuteFrameAdvance.AutoSize = true; @@ -352,7 +316,6 @@ this.grpOutputMethod.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); - } #endregion @@ -370,7 +333,6 @@ private BizHawk.WinForms.Controls.LocLabelEx BufferSizeUnitsLabel; private System.Windows.Forms.GroupBox grpOutputMethod; private System.Windows.Forms.RadioButton rbOutputMethodXAudio2; - private System.Windows.Forms.RadioButton rbOutputMethodDirectSound; private System.Windows.Forms.RadioButton rbOutputMethodOpenAL; private System.Windows.Forms.NumericUpDown nudRWFF; private System.Windows.Forms.CheckBox cbEnableRWFF; diff --git a/src/BizHawk.Client.EmuHawk/config/SoundConfig.cs b/src/BizHawk.Client.EmuHawk/config/SoundConfig.cs index 093a3d94c7..ecb21bf661 100644 --- a/src/BizHawk.Client.EmuHawk/config/SoundConfig.cs +++ b/src/BizHawk.Client.EmuHawk/config/SoundConfig.cs @@ -34,9 +34,8 @@ namespace BizHawk.Client.EmuHawk cbEnableRWFF.Checked = _config.SoundEnabledRWFF; cbMuteFrameAdvance.Checked = _config.MuteFrameAdvance; - rbOutputMethodDirectSound.Enabled = rbOutputMethodXAudio2.Enabled = HostCapabilityDetector.HasDirectX; + rbOutputMethodXAudio2.Enabled = HostCapabilityDetector.HasXAudio2; - rbOutputMethodDirectSound.Checked = _config.SoundOutputMethod == ESoundOutputMethod.DirectSound; rbOutputMethodXAudio2.Checked = _config.SoundOutputMethod == ESoundOutputMethod.XAudio2; rbOutputMethodOpenAL.Checked = _config.SoundOutputMethod == ESoundOutputMethod.OpenAL; BufferSizeNumeric.Value = _config.SoundBufferSizeMs; @@ -53,7 +52,6 @@ namespace BizHawk.Client.EmuHawk { if (!OSTailoredCode.IsUnixHost) { - if (rbOutputMethodDirectSound.Checked) return ESoundOutputMethod.DirectSound; if (rbOutputMethodXAudio2.Checked) return ESoundOutputMethod.XAudio2; } if (rbOutputMethodOpenAL.Checked) return ESoundOutputMethod.OpenAL; @@ -62,11 +60,6 @@ namespace BizHawk.Client.EmuHawk private void Ok_Click(object sender, EventArgs e) { - if (rbOutputMethodDirectSound.Checked && (int)BufferSizeNumeric.Value < 60) - { - DialogController.ShowMessageBox("Buffer size must be at least 60 milliseconds for DirectSound.", "Error", EMsgBoxIcon.Error); - return; - } _config.SoundEnabled = cbEnableMaster.Checked; _config.SoundEnabledNormal = cbEnableNormal.Checked; _config.SoundEnabledRWFF = cbEnableRWFF.Checked;