diff --git a/GUI.NET/Config/AudioInfo.cs b/GUI.NET/Config/AudioInfo.cs
index 8ed3b7f2..32aa7d9b 100644
--- a/GUI.NET/Config/AudioInfo.cs
+++ b/GUI.NET/Config/AudioInfo.cs
@@ -11,6 +11,7 @@ namespace Mesen.GUI.Config
{
public class AudioInfo
{
+ public string AudioDevice = "";
public bool EnableAudio = true;
public UInt32 AudioLatency = 100;
public UInt32 MasterVolume = 100;
@@ -37,6 +38,7 @@ namespace Mesen.GUI.Config
static public void ApplyConfig()
{
AudioInfo audioInfo = ConfigManager.Config.AudioInfo;
+ InteropEmu.SetAudioDevice(audioInfo.AudioDevice);
InteropEmu.SetAudioLatency(audioInfo.AudioLatency);
InteropEmu.SetMasterVolume(audioInfo.MasterVolume / 10d);
InteropEmu.SetChannelVolume(0, ConvertVolume(audioInfo.Square1Volume));
diff --git a/GUI.NET/Forms/BaseConfigForm.cs b/GUI.NET/Forms/BaseConfigForm.cs
index d8934941..0be0eb25 100644
--- a/GUI.NET/Forms/BaseConfigForm.cs
+++ b/GUI.NET/Forms/BaseConfigForm.cs
@@ -182,6 +182,11 @@ namespace Mesen.GUI.Forms
}
}
}
+ } else if(field.FieldType == typeof(string)) {
+ combo.SelectedItem = value;
+ if(combo.SelectedIndex < 0) {
+ combo.SelectedIndex = 0;
+ }
}
}
}
@@ -225,6 +230,8 @@ namespace Mesen.GUI.Forms
if(UInt32.TryParse(item, out numericValue)) {
field.SetValue(Entity, numericValue);
}
+ } else if(field.FieldType == typeof(string)) {
+ field.SetValue(Entity, ((ComboBox)kvp.Value).SelectedItem);
}
}
} catch {
diff --git a/GUI.NET/Forms/Config/frmAudioConfig.Designer.cs b/GUI.NET/Forms/Config/frmAudioConfig.Designer.cs
index 64e99670..1aff7779 100644
--- a/GUI.NET/Forms/Config/frmAudioConfig.Designer.cs
+++ b/GUI.NET/Forms/Config/frmAudioConfig.Designer.cs
@@ -43,6 +43,8 @@
this.lblLatencyMs = new System.Windows.Forms.Label();
this.lblAudioLatency = new System.Windows.Forms.Label();
this.cboSampleRate = new System.Windows.Forms.ComboBox();
+ this.lblAudioDevice = new System.Windows.Forms.Label();
+ this.cboAudioDevice = new System.Windows.Forms.ComboBox();
this.btnReset = new System.Windows.Forms.Button();
this.baseConfigPanel.SuspendLayout();
this.grpVolume.SuspendLayout();
@@ -55,7 +57,7 @@
// baseConfigPanel
//
this.baseConfigPanel.Controls.Add(this.btnReset);
- this.baseConfigPanel.Location = new System.Drawing.Point(0, 267);
+ this.baseConfigPanel.Location = new System.Drawing.Point(0, 295);
this.baseConfigPanel.Size = new System.Drawing.Size(470, 29);
this.baseConfigPanel.Controls.SetChildIndex(this.btnReset, 0);
//
@@ -63,7 +65,7 @@
//
this.tableLayoutPanel2.SetColumnSpan(this.grpVolume, 2);
this.grpVolume.Controls.Add(this.tableLayoutPanel1);
- this.grpVolume.Location = new System.Drawing.Point(3, 80);
+ this.grpVolume.Location = new System.Drawing.Point(3, 107);
this.grpVolume.Name = "grpVolume";
this.grpVolume.Size = new System.Drawing.Size(462, 185);
this.grpVolume.TabIndex = 2;
@@ -189,21 +191,23 @@
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel2.Controls.Add(this.chkEnableAudio, 0, 0);
- this.tableLayoutPanel2.Controls.Add(this.lblSampleRate, 0, 1);
- this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel2, 1, 2);
- this.tableLayoutPanel2.Controls.Add(this.lblAudioLatency, 0, 2);
- this.tableLayoutPanel2.Controls.Add(this.cboSampleRate, 1, 1);
- this.tableLayoutPanel2.Controls.Add(this.grpVolume, 0, 3);
+ this.tableLayoutPanel2.Controls.Add(this.lblSampleRate, 0, 2);
+ this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel2, 1, 3);
+ this.tableLayoutPanel2.Controls.Add(this.lblAudioLatency, 0, 3);
+ this.tableLayoutPanel2.Controls.Add(this.cboSampleRate, 1, 2);
+ this.tableLayoutPanel2.Controls.Add(this.grpVolume, 0, 4);
+ this.tableLayoutPanel2.Controls.Add(this.lblAudioDevice, 0, 1);
+ this.tableLayoutPanel2.Controls.Add(this.cboAudioDevice, 1, 1);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
- this.tableLayoutPanel2.RowCount = 4;
+ this.tableLayoutPanel2.RowCount = 5;
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
- this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
- this.tableLayoutPanel2.Size = new System.Drawing.Size(470, 296);
+ this.tableLayoutPanel2.Size = new System.Drawing.Size(470, 324);
this.tableLayoutPanel2.TabIndex = 3;
//
// chkEnableAudio
@@ -223,7 +227,7 @@
//
this.lblSampleRate.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblSampleRate.AutoSize = true;
- this.lblSampleRate.Location = new System.Drawing.Point(3, 33);
+ this.lblSampleRate.Location = new System.Drawing.Point(3, 60);
this.lblSampleRate.Name = "lblSampleRate";
this.lblSampleRate.Size = new System.Drawing.Size(71, 13);
this.lblSampleRate.TabIndex = 0;
@@ -233,7 +237,7 @@
//
this.flowLayoutPanel2.Controls.Add(this.nudLatency);
this.flowLayoutPanel2.Controls.Add(this.lblLatencyMs);
- this.flowLayoutPanel2.Location = new System.Drawing.Point(77, 53);
+ this.flowLayoutPanel2.Location = new System.Drawing.Point(77, 80);
this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel2.Name = "flowLayoutPanel2";
this.flowLayoutPanel2.Size = new System.Drawing.Size(78, 24);
@@ -275,7 +279,7 @@
//
this.lblAudioLatency.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblAudioLatency.AutoSize = true;
- this.lblAudioLatency.Location = new System.Drawing.Point(3, 58);
+ this.lblAudioLatency.Location = new System.Drawing.Point(3, 85);
this.lblAudioLatency.Name = "lblAudioLatency";
this.lblAudioLatency.Size = new System.Drawing.Size(48, 13);
this.lblAudioLatency.TabIndex = 0;
@@ -290,11 +294,30 @@
"22,050 Hz",
"44,100 Hz",
"48,000 Hz"});
- this.cboSampleRate.Location = new System.Drawing.Point(80, 29);
+ this.cboSampleRate.Location = new System.Drawing.Point(80, 56);
this.cboSampleRate.Name = "cboSampleRate";
this.cboSampleRate.Size = new System.Drawing.Size(75, 21);
this.cboSampleRate.TabIndex = 5;
//
+ // lblAudioDevice
+ //
+ this.lblAudioDevice.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.lblAudioDevice.AutoSize = true;
+ this.lblAudioDevice.Location = new System.Drawing.Point(3, 33);
+ this.lblAudioDevice.Name = "lblAudioDevice";
+ this.lblAudioDevice.Size = new System.Drawing.Size(44, 13);
+ this.lblAudioDevice.TabIndex = 6;
+ this.lblAudioDevice.Text = "Device:";
+ //
+ // cboAudioDevice
+ //
+ this.cboAudioDevice.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cboAudioDevice.FormattingEnabled = true;
+ this.cboAudioDevice.Location = new System.Drawing.Point(80, 29);
+ this.cboAudioDevice.Name = "cboAudioDevice";
+ this.cboAudioDevice.Size = new System.Drawing.Size(209, 21);
+ this.cboAudioDevice.TabIndex = 7;
+ //
// btnReset
//
this.btnReset.AutoSize = true;
@@ -310,7 +333,7 @@
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(470, 296);
+ this.ClientSize = new System.Drawing.Size(470, 324);
this.Controls.Add(this.tableLayoutPanel2);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
@@ -352,6 +375,7 @@
private System.Windows.Forms.Label lblSampleRate;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2;
private System.Windows.Forms.ComboBox cboSampleRate;
-
+ private System.Windows.Forms.Label lblAudioDevice;
+ private System.Windows.Forms.ComboBox cboAudioDevice;
}
}
\ No newline at end of file
diff --git a/GUI.NET/Forms/Config/frmAudioConfig.cs b/GUI.NET/Forms/Config/frmAudioConfig.cs
index 08c22202..2577122c 100644
--- a/GUI.NET/Forms/Config/frmAudioConfig.cs
+++ b/GUI.NET/Forms/Config/frmAudioConfig.cs
@@ -19,6 +19,8 @@ namespace Mesen.GUI.Forms.Config
Entity = ConfigManager.Config.AudioInfo;
+ cboAudioDevice.Items.AddRange(InteropEmu.GetAudioDevices().ToArray());
+
AddBinding("EnableAudio", chkEnableAudio);
AddBinding("MasterVolume", trkMaster);
AddBinding("Square1Volume", trkSquare1Vol);
@@ -28,6 +30,7 @@ namespace Mesen.GUI.Forms.Config
AddBinding("DmcVolume", trkDmcVol);
AddBinding("AudioLatency", nudLatency);
AddBinding("SampleRate", cboSampleRate);
+ AddBinding("AudioDevice", cboAudioDevice);
}
protected override void OnFormClosed(FormClosedEventArgs e)
diff --git a/GUI.NET/Forms/Config/frmAudioConfig.resx b/GUI.NET/Forms/Config/frmAudioConfig.resx
index 1af7de15..8766f298 100644
--- a/GUI.NET/Forms/Config/frmAudioConfig.resx
+++ b/GUI.NET/Forms/Config/frmAudioConfig.resx
@@ -117,4 +117,7 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ 17, 17
+
\ No newline at end of file
diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs
index 7d039d86..a9a4c0f0 100644
--- a/GUI.NET/InteropEmu.cs
+++ b/GUI.NET/InteropEmu.cs
@@ -87,6 +87,9 @@ namespace Mesen.GUI
[DllImport(DLLPath, EntryPoint="GetScreenSize")] private static extern void GetScreenSizeWrapper(out ScreenSize size);
+ [DllImport(DLLPath, EntryPoint= "GetAudioDevices")] private static extern IntPtr GetAudioDevicesWrapper();
+ [DllImport(DLLPath)] public static extern void SetAudioDevice(string audioDevice);
+
[DllImport(DLLPath)] public static extern void DebugInitialize();
[DllImport(DLLPath)] public static extern void DebugRelease();
[DllImport(DLLPath)] public static extern void DebugGetState(ref DebugState state);
@@ -237,6 +240,10 @@ namespace Mesen.GUI
public static string GetROMPath() { return PtrToStringUtf8(InteropEmu.GetROMPathWrapper()); }
public static string GetKeyName(UInt32 key) { return PtrToStringUtf8(InteropEmu.GetKeyNameWrapper(key)); }
+ public static List GetAudioDevices()
+ {
+ return new List(PtrToStringUtf8(InteropEmu.GetAudioDevicesWrapper()).Split(new string[1] { "||" }, StringSplitOptions.RemoveEmptyEntries ));
+ }
private static string PtrToStringUtf8(IntPtr ptr)
{
diff --git a/InteropDLL/ConsoleWrapper.cpp b/InteropDLL/ConsoleWrapper.cpp
index 1fd4332f..5c2716a9 100644
--- a/InteropDLL/ConsoleWrapper.cpp
+++ b/InteropDLL/ConsoleWrapper.cpp
@@ -220,6 +220,14 @@ namespace InteropEmu {
DllExport void __stdcall GetRgbPalette(uint32_t *paletteBuffer) { EmulationSettings::GetRgbPalette(paletteBuffer); }
DllExport void __stdcall SetRgbPalette(uint32_t *paletteBuffer) { EmulationSettings::SetRgbPalette(paletteBuffer); }
+ DllExport const char* __stdcall GetAudioDevices()
+ {
+ _returnString = _soundManager->GetAvailableDevices();
+ return _returnString.c_str();
+ }
+
+ DllExport void __stdcall SetAudioDevice(char* audioDevice) { _soundManager->SetAudioDevice(audioDevice); }
+
DllExport void __stdcall GetScreenSize(ScreenSize &size) { VideoDecoder::GetInstance()->GetScreenSize(size); }
}
}
\ No newline at end of file
diff --git a/Windows/SoundManager.cpp b/Windows/SoundManager.cpp
index f4aa09b3..47ea62fb 100644
--- a/Windows/SoundManager.cpp
+++ b/Windows/SoundManager.cpp
@@ -10,6 +10,8 @@ SoundManager::SoundManager(HWND hwnd)
_primaryBuffer = 0;
_secondaryBuffer = 0;
+ memset(&_audioDeviceID, 0, sizeof(_audioDeviceID));
+
if(InitializeDirectSound(44100)) {
SoundMixer::RegisterAudioDevice(this);
} else {
@@ -22,6 +24,52 @@ SoundManager::~SoundManager()
Release();
}
+bool CALLBACK SoundManager::DirectSoundEnumProc(LPGUID lpGUID, LPCSTR lpszDesc, LPCSTR lpszDrvName, LPVOID lpContext)
+{
+ vector *devices = (vector*)lpContext;
+
+ SoundDeviceInfo deviceInfo;
+ deviceInfo.description = lpszDesc;
+ if(lpGUID != nullptr) {
+ memcpy((void*)&deviceInfo.guid, lpGUID, 16);
+ } else {
+ memset((void*)&deviceInfo.guid, 0, 16);
+ }
+ devices->push_back(deviceInfo);
+
+ return true;
+}
+
+vector SoundManager::GetAvailableDeviceInfo()
+{
+ vector devices;
+ DirectSoundEnumerate((LPDSENUMCALLBACKA)SoundManager::DirectSoundEnumProc, &devices);
+ return devices;
+}
+
+string SoundManager::GetAvailableDevices()
+{
+ string deviceString;
+ for(SoundDeviceInfo device : GetAvailableDeviceInfo()) {
+ deviceString += device.description + "||"s;
+ }
+ return deviceString;
+}
+
+void SoundManager::SetAudioDevice(string deviceName)
+{
+ memset(&_audioDeviceID, 0, sizeof(_audioDeviceID));
+
+ for(SoundDeviceInfo device : GetAvailableDeviceInfo()) {
+ if(device.description.compare(deviceName) == 0) {
+ memcpy((void*)&_audioDeviceID, (void*)&device.guid, 16);
+ break;
+ }
+ }
+
+ _needReset = true;
+}
+
bool SoundManager::InitializeDirectSound(uint32_t sampleRate)
{
HRESULT result;
@@ -29,7 +77,7 @@ bool SoundManager::InitializeDirectSound(uint32_t sampleRate)
WAVEFORMATEX waveFormat;
// Initialize the direct sound interface pointer for the default sound device.
- result = DirectSoundCreate8(NULL, &_directSound, NULL);
+ result = DirectSoundCreate8(&_audioDeviceID, &_directSound, NULL);
if(FAILED(result)) {
return false;
}
@@ -107,6 +155,7 @@ bool SoundManager::InitializeDirectSound(uint32_t sampleRate)
void SoundManager::Release()
{
+ _needReset = false;
_lastWriteOffset = 0;
if(_secondaryBuffer) {
@@ -179,7 +228,7 @@ void SoundManager::Play()
void SoundManager::PlayBuffer(int16_t *soundBuffer, uint32_t soundBufferSize, uint32_t sampleRate)
{
- if(_sampleRate != sampleRate) {
+ if(_sampleRate != sampleRate || _needReset) {
Release();
InitializeDirectSound(sampleRate);
}
diff --git a/Windows/SoundManager.h b/Windows/SoundManager.h
index 52b5f12c..fdcd42e7 100644
--- a/Windows/SoundManager.h
+++ b/Windows/SoundManager.h
@@ -3,6 +3,12 @@
#include "stdafx.h"
#include "../Core/IAudioDevice.h"
+struct SoundDeviceInfo
+{
+ string description;
+ GUID guid;
+};
+
class SoundManager : public IAudioDevice
{
public:
@@ -15,7 +21,12 @@ public:
void Pause();
void Stop();
+ string GetAvailableDevices();
+ void SetAudioDevice(string deviceName);
+
private:
+ vector GetAvailableDeviceInfo();
+ static bool CALLBACK DirectSoundEnumProc(LPGUID lpGUID, LPCSTR lpszDesc, LPCSTR lpszDrvName, LPVOID lpContext);
bool InitializeDirectSound(uint32_t sampleRate);
void ShutdownDirectSound();
void ClearSecondaryBuffer();
@@ -23,6 +34,8 @@ private:
private:
HWND _hWnd;
+ GUID _audioDeviceID;
+ bool _needReset = false;
uint16_t _lastWriteOffset = 0;
uint16_t _previousLatency = 0;
diff --git a/Windows/Windows.vcxproj b/Windows/Windows.vcxproj
index e50e7a4a..d830abda 100644
--- a/Windows/Windows.vcxproj
+++ b/Windows/Windows.vcxproj
@@ -30,47 +30,48 @@
{7761E790-B42C-4179-8550-8365FF9EB23E}
Win32Proj
Windows
+ 8.1
StaticLibrary
true
v140
- Unicode
+ MultiByte
StaticLibrary
true
v140
- Unicode
+ MultiByte
StaticLibrary
false
v140
true
- Unicode
+ MultiByte
StaticLibrary
false
v140
true
- Unicode
+ MultiByte
StaticLibrary
false
v140
true
- Unicode
+ MultiByte
StaticLibrary
false
v140
true
- Unicode
+ MultiByte
diff --git a/Windows/stdafx.h b/Windows/stdafx.h
index 92f5cad0..4db3bd9d 100644
--- a/Windows/stdafx.h
+++ b/Windows/stdafx.h
@@ -43,4 +43,5 @@
using std::list;
using std::vector;
using std::shared_ptr;
-using std::string;
\ No newline at end of file
+using std::string;
+using namespace std::literals::string_literals;
\ No newline at end of file