Add UI for choosing between DirectSound / XAudio2.

Always use new sound output buffering (remove option).
This commit is contained in:
jdpurcell 2015-01-31 06:40:14 +00:00
parent 83e8abc963
commit 5eee1cd306
5 changed files with 186 additions and 59 deletions

View File

@ -111,6 +111,8 @@ namespace BizHawk.Client.Common
public enum EDispMethod { OpenGL, GdiPlus, SlimDX9 }; public enum EDispMethod { OpenGL, GdiPlus, SlimDX9 };
public enum ESoundOutputMethod { DirectSound, XAudio2, Dummy };
public enum EDispManagerAR { None, System, Custom }; public enum EDispManagerAR { None, System, Custom };
public enum SaveStateTypeE { Default, Binary, Text }; public enum SaveStateTypeE { Default, Binary, Text };
@ -224,13 +226,13 @@ namespace BizHawk.Client.Common
public int DispCustomUserARHeight = 1; public int DispCustomUserARHeight = 1;
// Sound options // Sound options
public ESoundOutputMethod SoundOutputMethod = ESoundOutputMethod.DirectSound;
public bool SoundEnabled = true; public bool SoundEnabled = true;
public bool MuteFrameAdvance = true; public bool MuteFrameAdvance = true;
public int SoundVolume = 100; // Range 0-100 public int SoundVolume = 100; // Range 0-100
public bool SoundThrottle = false; public bool SoundThrottle = false;
public string SoundDevice = ""; public string SoundDevice = "";
public int SoundBufferSizeMs = 100; public int SoundBufferSizeMs = 100;
public bool UseNewOutputBuffer = false;
// Log Window // Log Window
public bool LogWindowSaveWindowPosition = true; public bool LogWindowSaveWindowPosition = true;

View File

@ -281,7 +281,13 @@ namespace BizHawk.Client.EmuHawk
try { GlobalWin.Sound = new Sound(Handle); } try { GlobalWin.Sound = new Sound(Handle); }
catch catch
{ {
MessageBox.Show("Couldn't initialize DirectSound! Things may go poorly for you. Try changing your sound driver to 41khz instead of 48khz in mmsys.cpl.", "Initialization Error", MessageBoxButtons.OK, MessageBoxIcon.Error); string message = "Couldn't initialize sound device! Try changing the output method in Sound config.";
if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.DirectSound)
message = "Couldn't initialize DirectSound! Things may go poorly for you. Try changing your sound driver to 44.1khz instead of 48khz in mmsys.cpl.";
MessageBox.Show(message, "Initialization Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
Global.Config.SoundOutputMethod = Config.ESoundOutputMethod.Dummy;
GlobalWin.Sound = new Sound(Handle);
} }
#else #else
Global.Sound = new Sound(); Global.Sound = new Sound();
@ -1506,19 +1512,10 @@ namespace BizHawk.Client.EmuHawk
// note that the avi dumper has already rewired the emulator itself in this case. // note that the avi dumper has already rewired the emulator itself in this case.
GlobalWin.Sound.SetAsyncInputPin(_dumpProxy); GlobalWin.Sound.SetAsyncInputPin(_dumpProxy);
} }
else if (Global.Config.SoundThrottle || Global.Config.UseNewOutputBuffer)
{
// for sound throttle and new output buffer, use sync mode
Global.Emulator.EndAsyncSound();
GlobalWin.Sound.SetSyncInputPin(Global.Emulator.SyncSoundProvider);
}
else else
{ {
// for vsync\clock throttle modes through old output buffer, use async Global.Emulator.EndAsyncSound();
GlobalWin.Sound.SetAsyncInputPin( GlobalWin.Sound.SetSyncInputPin(Global.Emulator.SyncSoundProvider);
!Global.Emulator.StartAsyncSound()
? new MetaspuAsync(Global.Emulator.SyncSoundProvider, ESynchMethod.ESynchMethod_V)
: Global.Emulator.SoundProvider);
} }
} }

View File

@ -43,8 +43,12 @@ namespace BizHawk.Client.EmuHawk
public Sound(IntPtr mainWindowHandle) public Sound(IntPtr mainWindowHandle)
{ {
_soundOutput = new DirectSoundSoundOutput(this, mainWindowHandle); if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.DirectSound)
//_soundOutput = new XAudio2SoundOutput(this); _soundOutput = new DirectSoundSoundOutput(this, mainWindowHandle);
else if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.XAudio2)
_soundOutput = new XAudio2SoundOutput(this);
else
_soundOutput = new DummySoundOutput(this);
} }
public void Dispose() public void Dispose()
@ -267,7 +271,7 @@ namespace BizHawk.Client.EmuHawk
public static IEnumerable<string> GetDeviceNames() public static IEnumerable<string> GetDeviceNames()
{ {
return DirectSound.GetDevices().Select(d => d.Description); return DirectSound.GetDevices().Select(d => d.Description).ToList();
} }
private int BufferSizeSamples { get; set; } private int BufferSizeSamples { get; set; }
@ -429,7 +433,7 @@ namespace BizHawk.Client.EmuHawk
{ {
using (XAudio2 device = new XAudio2()) using (XAudio2 device = new XAudio2())
{ {
return Enumerable.Range(0, device.DeviceCount).Select(n => device.GetDeviceDetails(n).DisplayName); return Enumerable.Range(0, device.DeviceCount).Select(n => device.GetDeviceDetails(n).DisplayName).ToList();
} }
} }
@ -475,13 +479,13 @@ namespace BizHawk.Client.EmuHawk
public int CalculateSamplesNeeded() public int CalculateSamplesNeeded()
{ {
long samplesAwaitingPlayback = _runningSamplesQueued - _sourceVoice.State.SamplesPlayed;
bool isInitializing = _runningSamplesQueued == 0; bool isInitializing = _runningSamplesQueued == 0;
bool detectedUnderrun = !isInitializing && _sourceVoice.State.BuffersQueued == 0; bool detectedUnderrun = !isInitializing && _sourceVoice.State.BuffersQueued == 0;
if (detectedUnderrun) if (detectedUnderrun)
{ {
_sound.OnUnderrun(); _sound.OnUnderrun();
} }
long samplesAwaitingPlayback = _runningSamplesQueued - _sourceVoice.State.SamplesPlayed;
int samplesNeeded = (int)Math.Max(BufferSizeSamples - samplesAwaitingPlayback, 0); int samplesNeeded = (int)Math.Max(BufferSizeSamples - samplesAwaitingPlayback, 0);
if ((isInitializing && _sound.InitializeBufferWithSilence) || (detectedUnderrun && _sound.RecoverFromUnderrunsWithSilence)) if ((isInitializing && _sound.InitializeBufferWithSilence) || (detectedUnderrun && _sound.RecoverFromUnderrunsWithSilence))
{ {
@ -499,13 +503,78 @@ namespace BizHawk.Client.EmuHawk
// TODO: Re-use these buffers // TODO: Re-use these buffers
byte[] bytes = new byte[sampleCount * Sound.BlockAlign]; byte[] bytes = new byte[sampleCount * Sound.BlockAlign];
Buffer.BlockCopy(samples, 0, bytes, 0, bytes.Length); Buffer.BlockCopy(samples, 0, bytes, 0, bytes.Length);
_sourceVoice.SubmitSourceBuffer(new AudioBuffer { _sourceVoice.SubmitSourceBuffer(new AudioBuffer
{
AudioBytes = bytes.Length, AudioBytes = bytes.Length,
AudioData = new DataStream(bytes, true, false) AudioData = new DataStream(bytes, true, false)
}); });
_runningSamplesQueued += sampleCount; _runningSamplesQueued += sampleCount;
} }
} }
public class DummySoundOutput : ISoundOutput
{
private Sound _sound;
private int _remainingSamples;
private long _lastWriteTime;
public DummySoundOutput(Sound sound)
{
_sound = sound;
}
public void Dispose()
{
}
private int BufferSizeSamples { get; set; }
public int MaxSamplesDeficit { get; private set; }
public void ApplyVolumeSettings(double volume)
{
}
public void StartSound()
{
BufferSizeSamples = Sound.MillisecondsToSamples(Global.Config.SoundBufferSizeMs);
MaxSamplesDeficit = BufferSizeSamples;
_lastWriteTime = 0;
}
public void StopSound()
{
BufferSizeSamples = 0;
}
public int CalculateSamplesNeeded()
{
Start:
long currentWriteTime = Stopwatch.GetTimestamp();
if (_lastWriteTime != 0)
{
double elapsedSeconds = (currentWriteTime - _lastWriteTime) / (double)Stopwatch.Frequency;
if (elapsedSeconds < 0.001)
{
// Due to rounding errors this doesn't work too well in audio throttle mode unless we let more time pass
Thread.Sleep(1);
goto Start;
}
_remainingSamples -= (int)Math.Round(elapsedSeconds * Sound.SampleRate);
if (_remainingSamples < 0) _remainingSamples = 0;
}
int samplesNeeded = BufferSizeSamples - _remainingSamples;
_lastWriteTime = currentWriteTime;
return samplesNeeded;
}
public void WriteSamples(short[] samples, int sampleCount)
{
if (sampleCount == 0) return;
_remainingSamples += sampleCount;
}
}
#else #else
// Dummy implementation for non-Windows platforms for now. // Dummy implementation for non-Windows platforms for now.
public class Sound public class Sound

View File

@ -35,16 +35,19 @@
this.SoundVolGroup = new System.Windows.Forms.GroupBox(); this.SoundVolGroup = new System.Windows.Forms.GroupBox();
this.SoundVolBar = new System.Windows.Forms.TrackBar(); this.SoundVolBar = new System.Windows.Forms.TrackBar();
this.SoundVolNumeric = new System.Windows.Forms.NumericUpDown(); this.SoundVolNumeric = new System.Windows.Forms.NumericUpDown();
this.UseNewOutputBuffer = new System.Windows.Forms.CheckBox();
this.listBoxSoundDevices = new System.Windows.Forms.ListBox(); this.listBoxSoundDevices = new System.Windows.Forms.ListBox();
this.SoundDeviceLabel = new System.Windows.Forms.Label(); this.SoundDeviceLabel = new System.Windows.Forms.Label();
this.BufferSizeLabel = new System.Windows.Forms.Label(); this.BufferSizeLabel = new System.Windows.Forms.Label();
this.BufferSizeNumeric = new System.Windows.Forms.NumericUpDown(); this.BufferSizeNumeric = new System.Windows.Forms.NumericUpDown();
this.BufferSizeUnitsLabel = new System.Windows.Forms.Label(); this.BufferSizeUnitsLabel = new System.Windows.Forms.Label();
this.grpOutputMethod = new System.Windows.Forms.GroupBox();
this.rbOutputMethodXAudio2 = new System.Windows.Forms.RadioButton();
this.rbOutputMethodDirectSound = new System.Windows.Forms.RadioButton();
this.SoundVolGroup.SuspendLayout(); this.SoundVolGroup.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.SoundVolBar)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.SoundVolBar)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.SoundVolNumeric)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.SoundVolNumeric)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.BufferSizeNumeric)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.BufferSizeNumeric)).BeginInit();
this.grpOutputMethod.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
// //
// Cancel // Cancel
@ -62,7 +65,6 @@
// OK // OK
// //
this.OK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.OK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.OK.DialogResult = System.Windows.Forms.DialogResult.OK;
this.OK.Location = new System.Drawing.Point(236, 244); this.OK.Location = new System.Drawing.Point(236, 244);
this.OK.Name = "OK"; this.OK.Name = "OK";
this.OK.Size = new System.Drawing.Size(75, 23); this.OK.Size = new System.Drawing.Size(75, 23);
@ -74,7 +76,7 @@
// SoundOnCheckBox // SoundOnCheckBox
// //
this.SoundOnCheckBox.AutoSize = true; this.SoundOnCheckBox.AutoSize = true;
this.SoundOnCheckBox.Location = new System.Drawing.Point(147, 12); this.SoundOnCheckBox.Location = new System.Drawing.Point(108, 31);
this.SoundOnCheckBox.Name = "SoundOnCheckBox"; this.SoundOnCheckBox.Name = "SoundOnCheckBox";
this.SoundOnCheckBox.Size = new System.Drawing.Size(74, 17); this.SoundOnCheckBox.Size = new System.Drawing.Size(74, 17);
this.SoundOnCheckBox.TabIndex = 3; this.SoundOnCheckBox.TabIndex = 3;
@ -85,7 +87,7 @@
// MuteFrameAdvance // MuteFrameAdvance
// //
this.MuteFrameAdvance.AutoSize = true; this.MuteFrameAdvance.AutoSize = true;
this.MuteFrameAdvance.Location = new System.Drawing.Point(147, 35); this.MuteFrameAdvance.Location = new System.Drawing.Point(108, 54);
this.MuteFrameAdvance.Name = "MuteFrameAdvance"; this.MuteFrameAdvance.Name = "MuteFrameAdvance";
this.MuteFrameAdvance.Size = new System.Drawing.Size(128, 17); this.MuteFrameAdvance.Size = new System.Drawing.Size(128, 17);
this.MuteFrameAdvance.TabIndex = 4; this.MuteFrameAdvance.TabIndex = 4;
@ -123,23 +125,13 @@
this.SoundVolNumeric.TabIndex = 1; this.SoundVolNumeric.TabIndex = 1;
this.SoundVolNumeric.ValueChanged += new System.EventHandler(this.SoundVolNumeric_ValueChanged); this.SoundVolNumeric.ValueChanged += new System.EventHandler(this.SoundVolNumeric_ValueChanged);
// //
// UseNewOutputBuffer
//
this.UseNewOutputBuffer.AutoSize = true;
this.UseNewOutputBuffer.Location = new System.Drawing.Point(147, 58);
this.UseNewOutputBuffer.Name = "UseNewOutputBuffer";
this.UseNewOutputBuffer.Size = new System.Drawing.Size(205, 17);
this.UseNewOutputBuffer.TabIndex = 5;
this.UseNewOutputBuffer.Text = "Use New Output Buffer (Experimental)";
this.UseNewOutputBuffer.UseVisualStyleBackColor = true;
//
// listBoxSoundDevices // listBoxSoundDevices
// //
this.listBoxSoundDevices.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 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.Left)
| System.Windows.Forms.AnchorStyles.Right))); | System.Windows.Forms.AnchorStyles.Right)));
this.listBoxSoundDevices.FormattingEnabled = true; this.listBoxSoundDevices.FormattingEnabled = true;
this.listBoxSoundDevices.Location = new System.Drawing.Point(108, 102); this.listBoxSoundDevices.Location = new System.Drawing.Point(108, 108);
this.listBoxSoundDevices.Name = "listBoxSoundDevices"; this.listBoxSoundDevices.Name = "listBoxSoundDevices";
this.listBoxSoundDevices.Size = new System.Drawing.Size(284, 95); this.listBoxSoundDevices.Size = new System.Drawing.Size(284, 95);
this.listBoxSoundDevices.TabIndex = 7; this.listBoxSoundDevices.TabIndex = 7;
@ -147,7 +139,7 @@
// SoundDeviceLabel // SoundDeviceLabel
// //
this.SoundDeviceLabel.AutoSize = true; this.SoundDeviceLabel.AutoSize = true;
this.SoundDeviceLabel.Location = new System.Drawing.Point(108, 86); this.SoundDeviceLabel.Location = new System.Drawing.Point(105, 92);
this.SoundDeviceLabel.Name = "SoundDeviceLabel"; this.SoundDeviceLabel.Name = "SoundDeviceLabel";
this.SoundDeviceLabel.Size = new System.Drawing.Size(78, 13); this.SoundDeviceLabel.Size = new System.Drawing.Size(78, 13);
this.SoundDeviceLabel.TabIndex = 6; this.SoundDeviceLabel.TabIndex = 6;
@ -173,7 +165,7 @@
0, 0,
0}); 0});
this.BufferSizeNumeric.Minimum = new decimal(new int[] { this.BufferSizeNumeric.Minimum = new decimal(new int[] {
60, 30,
0, 0,
0, 0,
0}); 0});
@ -196,6 +188,41 @@
this.BufferSizeUnitsLabel.TabIndex = 10; this.BufferSizeUnitsLabel.TabIndex = 10;
this.BufferSizeUnitsLabel.Text = "milliseconds"; this.BufferSizeUnitsLabel.Text = "milliseconds";
// //
// grpOutputMethod
//
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, 68);
this.grpOutputMethod.TabIndex = 5;
this.grpOutputMethod.TabStop = false;
this.grpOutputMethod.Text = "Output Method";
//
// rbOutputMethodXAudio2
//
this.rbOutputMethodXAudio2.AutoSize = true;
this.rbOutputMethodXAudio2.Location = new System.Drawing.Point(6, 42);
this.rbOutputMethodXAudio2.Name = "rbOutputMethodXAudio2";
this.rbOutputMethodXAudio2.Size = new System.Drawing.Size(65, 17);
this.rbOutputMethodXAudio2.TabIndex = 1;
this.rbOutputMethodXAudio2.TabStop = true;
this.rbOutputMethodXAudio2.Text = "XAudio2";
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);
//
// SoundConfig // SoundConfig
// //
this.AcceptButton = this.OK; this.AcceptButton = this.OK;
@ -203,12 +230,12 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.Cancel; this.CancelButton = this.Cancel;
this.ClientSize = new System.Drawing.Size(404, 279); this.ClientSize = new System.Drawing.Size(404, 279);
this.Controls.Add(this.grpOutputMethod);
this.Controls.Add(this.BufferSizeUnitsLabel); this.Controls.Add(this.BufferSizeUnitsLabel);
this.Controls.Add(this.BufferSizeNumeric); this.Controls.Add(this.BufferSizeNumeric);
this.Controls.Add(this.BufferSizeLabel); this.Controls.Add(this.BufferSizeLabel);
this.Controls.Add(this.SoundDeviceLabel); this.Controls.Add(this.SoundDeviceLabel);
this.Controls.Add(this.listBoxSoundDevices); this.Controls.Add(this.listBoxSoundDevices);
this.Controls.Add(this.UseNewOutputBuffer);
this.Controls.Add(this.SoundVolGroup); this.Controls.Add(this.SoundVolGroup);
this.Controls.Add(this.MuteFrameAdvance); this.Controls.Add(this.MuteFrameAdvance);
this.Controls.Add(this.SoundOnCheckBox); this.Controls.Add(this.SoundOnCheckBox);
@ -225,6 +252,8 @@
((System.ComponentModel.ISupportInitialize)(this.SoundVolBar)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.SoundVolBar)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.SoundVolNumeric)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.SoundVolNumeric)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.BufferSizeNumeric)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.BufferSizeNumeric)).EndInit();
this.grpOutputMethod.ResumeLayout(false);
this.grpOutputMethod.PerformLayout();
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout(); this.PerformLayout();
@ -239,11 +268,13 @@
private System.Windows.Forms.GroupBox SoundVolGroup; private System.Windows.Forms.GroupBox SoundVolGroup;
private System.Windows.Forms.NumericUpDown SoundVolNumeric; private System.Windows.Forms.NumericUpDown SoundVolNumeric;
private System.Windows.Forms.TrackBar SoundVolBar; private System.Windows.Forms.TrackBar SoundVolBar;
private System.Windows.Forms.CheckBox UseNewOutputBuffer;
private System.Windows.Forms.ListBox listBoxSoundDevices; private System.Windows.Forms.ListBox listBoxSoundDevices;
private System.Windows.Forms.Label SoundDeviceLabel; private System.Windows.Forms.Label SoundDeviceLabel;
private System.Windows.Forms.Label BufferSizeLabel; private System.Windows.Forms.Label BufferSizeLabel;
private System.Windows.Forms.NumericUpDown BufferSizeNumeric; private System.Windows.Forms.NumericUpDown BufferSizeNumeric;
private System.Windows.Forms.Label BufferSizeUnitsLabel; private System.Windows.Forms.Label BufferSizeUnitsLabel;
private System.Windows.Forms.GroupBox grpOutputMethod;
private System.Windows.Forms.RadioButton rbOutputMethodXAudio2;
private System.Windows.Forms.RadioButton rbOutputMethodDirectSound;
} }
} }

View File

@ -1,4 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Client.Common; using BizHawk.Client.Common;
@ -20,15 +22,57 @@ namespace BizHawk.Client.EmuHawk
SoundOnCheckBox.Checked = Global.Config.SoundEnabled; SoundOnCheckBox.Checked = Global.Config.SoundEnabled;
MuteFrameAdvance.Checked = Global.Config.MuteFrameAdvance; MuteFrameAdvance.Checked = Global.Config.MuteFrameAdvance;
UseNewOutputBuffer.Checked = Global.Config.UseNewOutputBuffer; rbOutputMethodDirectSound.Checked = Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.DirectSound;
rbOutputMethodXAudio2.Checked = Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.XAudio2;
BufferSizeNumeric.Value = Global.Config.SoundBufferSizeMs; BufferSizeNumeric.Value = Global.Config.SoundBufferSizeMs;
SoundVolBar.Value = Global.Config.SoundVolume; SoundVolBar.Value = Global.Config.SoundVolume;
SoundVolNumeric.Value = Global.Config.SoundVolume; SoundVolNumeric.Value = Global.Config.SoundVolume;
UpdateSoundDialog(); UpdateSoundDialog();
_programmaticallyChangingValue = false;
}
private void OK_Click(object sender, EventArgs e)
{
if (rbOutputMethodDirectSound.Checked && (int)BufferSizeNumeric.Value < 60)
{
MessageBox.Show("Buffer size must be at least 60 milliseconds for DirectSound.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
var oldOutputMethod = Global.Config.SoundOutputMethod;
Global.Config.SoundEnabled = SoundOnCheckBox.Checked;
Global.Config.MuteFrameAdvance = MuteFrameAdvance.Checked;
if (rbOutputMethodDirectSound.Checked) Global.Config.SoundOutputMethod = Config.ESoundOutputMethod.DirectSound;
if (rbOutputMethodXAudio2.Checked) Global.Config.SoundOutputMethod = Config.ESoundOutputMethod.XAudio2;
Global.Config.SoundBufferSizeMs = (int)BufferSizeNumeric.Value;
Global.Config.SoundVolume = SoundVolBar.Value;
Global.Config.SoundDevice = (string)listBoxSoundDevices.SelectedItem ?? "<default>";
GlobalWin.Sound.StopSound();
if (Global.Config.SoundOutputMethod != oldOutputMethod)
{
GlobalWin.Sound.Dispose();
GlobalWin.Sound = new Sound(GlobalWin.MainForm.Handle);
}
GlobalWin.Sound.StartSound();
GlobalWin.OSD.AddMessage("Sound settings saved");
DialogResult = DialogResult.OK;
}
private void Cancel_Click(object sender, EventArgs e)
{
GlobalWin.OSD.AddMessage("Sound config aborted");
Close();
}
private void PopulateDeviceList()
{
IEnumerable<string> deviceNames = Enumerable.Empty<string>();
if (rbOutputMethodDirectSound.Checked) deviceNames = DirectSoundSoundOutput.GetDeviceNames();
if (rbOutputMethodXAudio2.Checked) deviceNames = XAudio2SoundOutput.GetDeviceNames();
listBoxSoundDevices.Items.Clear();
listBoxSoundDevices.Items.Add("<default>"); listBoxSoundDevices.Items.Add("<default>");
listBoxSoundDevices.SelectedIndex = 0; listBoxSoundDevices.SelectedIndex = 0;
foreach (var name in DirectSoundSoundOutput.GetDeviceNames()) foreach (var name in deviceNames)
{ {
listBoxSoundDevices.Items.Add(name); listBoxSoundDevices.Items.Add(name);
if (name == Global.Config.SoundDevice) if (name == Global.Config.SoundDevice)
@ -36,28 +80,12 @@ namespace BizHawk.Client.EmuHawk
listBoxSoundDevices.SelectedItem = name; listBoxSoundDevices.SelectedItem = name;
} }
} }
_programmaticallyChangingValue = false;
} }
private void OK_Click(object sender, EventArgs e) private void OutputMethodRadioButtons_CheckedChanged(object sender, EventArgs e)
{ {
Global.Config.SoundEnabled = SoundOnCheckBox.Checked; if (!((RadioButton)sender).Checked) return;
Global.Config.MuteFrameAdvance = MuteFrameAdvance.Checked; PopulateDeviceList();
Global.Config.UseNewOutputBuffer = UseNewOutputBuffer.Checked;
Global.Config.SoundBufferSizeMs = (int)BufferSizeNumeric.Value;
Global.Config.SoundVolume = SoundVolBar.Value;
Global.Config.SoundDevice = (string)listBoxSoundDevices.SelectedItem ?? "<default>";
GlobalWin.Sound.StopSound();
GlobalWin.Sound.StartSound();
GlobalWin.OSD.AddMessage("Sound settings saved");
Close();
}
private void Cancel_Click(object sender, EventArgs e)
{
GlobalWin.OSD.AddMessage("Sound config aborted");
Close();
} }
private void trackBar1_Scroll(object sender, EventArgs e) private void trackBar1_Scroll(object sender, EventArgs e)