diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj
index 0db3a1ed..6e58dec4 100644
--- a/Core/Core.vcxproj
+++ b/Core/Core.vcxproj
@@ -561,6 +561,7 @@
+
@@ -1050,6 +1051,7 @@
Create
Create
+
diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters
index 62177a8b..6f402fce 100644
--- a/Core/Core.vcxproj.filters
+++ b/Core/Core.vcxproj.filters
@@ -1471,6 +1471,9 @@
Rewinder
+
+ Nes\APU\Filters
+
@@ -1761,5 +1764,8 @@
Rewinder
+
+ Nes\APU\Filters
+
\ No newline at end of file
diff --git a/Core/EmulationSettings.h b/Core/EmulationSettings.h
index 24655093..30bf4737 100644
--- a/Core/EmulationSettings.h
+++ b/Core/EmulationSettings.h
@@ -542,6 +542,20 @@ enum class StereoFilter
None = 0,
Delay = 1,
Panning = 2,
+ CombFilter = 3,
+};
+
+struct AudioFilterSettings
+{
+ StereoFilter StereoFilter = StereoFilter::None;
+ double Angle = 0;
+ int32_t Delay = 0;
+ int32_t Strength = 0;
+
+ double ReverbDelay = 0;
+ double ReverbStrength = 0;
+
+ int32_t CrossFadeRatio = 0;
};
enum class InputDisplayPosition
@@ -618,12 +632,7 @@ private:
double _masterVolume = 1.0;
double _volumeReduction = 0.75;
uint32_t _sampleRate = 48000;
- StereoFilter _stereoFilter = StereoFilter::None;
- int32_t _stereoDelay = 0;
- double _stereoAngle = 0;
- double _reverbStrength = 0;
- double _reverbDelay = 0;
- uint32_t _crossFeedRatio = 0;
+ AudioFilterSettings _audioFilterSettings;
NesModel _model = NesModel::Auto;
PpuModel _ppuModel = PpuModel::Ppu2C02;
@@ -870,60 +879,15 @@ public:
_audioSettingsChanged = true;
}
- void SetStereoFilter(StereoFilter stereoFilter)
+ void SetAudioFilterSettings(AudioFilterSettings settings)
{
- _stereoFilter = stereoFilter;
+ _audioFilterSettings = settings;
_audioSettingsChanged = true;
}
- void SetStereoDelay(int32_t delay)
+ AudioFilterSettings GetAudioFilterSettings()
{
- _stereoDelay = delay;
- _audioSettingsChanged = true;
- }
-
- void SetStereoPanningAngle(double angle)
- {
- _stereoAngle = angle;
- _audioSettingsChanged = true;
- }
-
- void SetReverbParameters(double strength, double delay)
- {
- _reverbStrength = strength;
- _reverbDelay = delay;
- _audioSettingsChanged = true;
- }
-
- StereoFilter GetStereoFilter()
- {
- return _stereoFilter;
- }
-
- int32_t GetStereoDelay()
- {
- return _stereoDelay;
- }
-
- double GetStereoPanningAngle()
- {
- return _stereoAngle;
- }
-
- double GetReverbStrength()
- {
- return _reverbStrength;
- }
-
- double GetReverbDelay()
- {
- return _reverbDelay;
- }
-
- void SetCrossFeedRatio(uint32_t ratio)
- {
- _crossFeedRatio = ratio;
- _audioSettingsChanged = true;
+ return _audioFilterSettings;
}
bool NeedAudioSettingsUpdate()
@@ -934,12 +898,7 @@ public:
}
return value;
}
-
- uint32_t GetCrossFeedRatio()
- {
- return _crossFeedRatio;
- }
-
+
//0: No limit, Number: % of default speed (50/60fps)
void SetEmulationSpeed(uint32_t emulationSpeed, bool displaySpeed = false)
{
diff --git a/Core/SoundMixer.cpp b/Core/SoundMixer.cpp
index 1f4d346d..492a4f22 100644
--- a/Core/SoundMixer.cpp
+++ b/Core/SoundMixer.cpp
@@ -142,20 +142,23 @@ void SoundMixer::PlayAudioBuffer(uint32_t time)
}
}
- if(_settings->GetReverbStrength() > 0) {
- _reverbFilter.ApplyFilter(_outputBuffer, sampleCount, _sampleRate, _settings->GetReverbStrength(), _settings->GetReverbDelay());
+ AudioFilterSettings filterSettings = _settings->GetAudioFilterSettings();
+
+ if(filterSettings.ReverbStrength > 0) {
+ _reverbFilter.ApplyFilter(_outputBuffer, sampleCount, _sampleRate, filterSettings.ReverbStrength, filterSettings.ReverbDelay);
} else {
_reverbFilter.ResetFilter();
}
- switch(_settings->GetStereoFilter()) {
+ switch(filterSettings.StereoFilter) {
case StereoFilter::None: break;
- case StereoFilter::Delay: _stereoDelay.ApplyFilter(_outputBuffer, sampleCount, _sampleRate, _settings->GetStereoDelay()); break;
- case StereoFilter::Panning: _stereoPanning.ApplyFilter(_outputBuffer, sampleCount, _settings->GetStereoPanningAngle()); break;
+ case StereoFilter::Delay: _stereoDelay.ApplyFilter(_outputBuffer, sampleCount, _sampleRate, filterSettings.Delay); break;
+ case StereoFilter::Panning: _stereoPanning.ApplyFilter(_outputBuffer, sampleCount, filterSettings.Angle); break;
+ case StereoFilter::CombFilter: _stereoCombFilter.ApplyFilter(_outputBuffer, sampleCount, _sampleRate, filterSettings.Delay, filterSettings.Strength); break;
}
- if(_settings->GetCrossFeedRatio() > 0) {
- _crossFeedFilter.ApplyFilter(_outputBuffer, sampleCount, _settings->GetCrossFeedRatio());
+ if(filterSettings.CrossFadeRatio > 0) {
+ _crossFeedFilter.ApplyFilter(_outputBuffer, sampleCount, filterSettings.CrossFadeRatio);
}
if(rewindManager && rewindManager->SendAudio(_outputBuffer, (uint32_t)sampleCount, _sampleRate)) {
diff --git a/Core/SoundMixer.h b/Core/SoundMixer.h
index e82183d2..2bf2135a 100644
--- a/Core/SoundMixer.h
+++ b/Core/SoundMixer.h
@@ -8,6 +8,7 @@
#include "Snapshotable.h"
#include "StereoPanningFilter.h"
#include "StereoDelayFilter.h"
+#include "StereoCombFilter.h"
#include "ReverbFilter.h"
#include "CrossFeedFilter.h"
@@ -47,6 +48,7 @@ private:
LowPassFilter _lowPassFilter;
StereoPanningFilter _stereoPanning;
StereoDelayFilter _stereoDelay;
+ StereoCombFilter _stereoCombFilter;
ReverbFilter _reverbFilter;
int16_t _previousOutputLeft = 0;
diff --git a/Core/StereoCombFilter.cpp b/Core/StereoCombFilter.cpp
new file mode 100644
index 00000000..f9af7570
--- /dev/null
+++ b/Core/StereoCombFilter.cpp
@@ -0,0 +1,29 @@
+#include "stdafx.h"
+#include "StereoCombFilter.h"
+
+void StereoCombFilter::ApplyFilter(int16_t * stereoBuffer, size_t sampleCount, uint32_t sampleRate, int32_t delay, uint32_t strength)
+{
+ size_t delaySampleCount = (int32_t)((double)delay / 1000 * sampleRate);
+ if(delaySampleCount != _lastDelay) {
+ _delayedSamplesLeft.clear();
+ _delayedSamplesRight.clear();
+ for(size_t i = 0; i < delaySampleCount; i++) {
+ _delayedSamplesLeft.push_back(0);
+ _delayedSamplesRight.push_back(0);
+ }
+ }
+ _lastDelay = delaySampleCount;
+
+ double ratio = strength == 0 ? 0 : strength / 100.0;
+ for(size_t i = 0; i < sampleCount * 2; i += 2) {
+ _delayedSamplesLeft.push_back(stereoBuffer[i]);
+ _delayedSamplesRight.push_back(stereoBuffer[i + 1]);
+
+ int16_t delayedSample = (_delayedSamplesRight.front() + _delayedSamplesLeft.front()) / 2;
+ int16_t monoSample = (stereoBuffer[i] + stereoBuffer[i + 1]) / 2;
+ stereoBuffer[i] = monoSample + (int16_t)(delayedSample * ratio);
+ stereoBuffer[i + 1] = monoSample - (int16_t)(delayedSample * ratio);
+ _delayedSamplesLeft.pop_front();
+ _delayedSamplesRight.pop_front();
+ }
+}
diff --git a/Core/StereoCombFilter.h b/Core/StereoCombFilter.h
new file mode 100644
index 00000000..869cfcdf
--- /dev/null
+++ b/Core/StereoCombFilter.h
@@ -0,0 +1,13 @@
+#pragma once
+#include "stdafx.h"
+#include
+
+class StereoCombFilter
+{
+ std::deque _delayedSamplesLeft;
+ std::deque _delayedSamplesRight;
+ size_t _lastDelay = 0;
+
+public:
+ void ApplyFilter(int16_t* stereoBuffer, size_t sampleCount, uint32_t sampleRate, int32_t delay, uint32_t strength);
+};
\ No newline at end of file
diff --git a/Core/StereoDelayFilter.cpp b/Core/StereoDelayFilter.cpp
index 9e3e3b85..3f1536d2 100644
--- a/Core/StereoDelayFilter.cpp
+++ b/Core/StereoDelayFilter.cpp
@@ -1,4 +1,5 @@
#include "stdafx.h"
+#include
#include "StereoDelayFilter.h"
void StereoDelayFilter::ApplyFilter(int16_t* stereoBuffer, size_t sampleCount, uint32_t sampleRate, int32_t stereoDelay)
diff --git a/Core/StereoDelayFilter.h b/Core/StereoDelayFilter.h
index 28d83c55..838b96ef 100644
--- a/Core/StereoDelayFilter.h
+++ b/Core/StereoDelayFilter.h
@@ -1,8 +1,6 @@
#pragma once
#include "stdafx.h"
#include
-#include
-#include "EmulationSettings.h"
class StereoDelayFilter
{
diff --git a/GUI.NET/Config/AudioInfo.cs b/GUI.NET/Config/AudioInfo.cs
index 460445d7..bcef692d 100644
--- a/GUI.NET/Config/AudioInfo.cs
+++ b/GUI.NET/Config/AudioInfo.cs
@@ -49,9 +49,13 @@ namespace Mesen.GUI.Config
public InteropEmu.StereoFilter StereoFilter;
[MinMax(0, 100)] public Int32 StereoDelay = 15;
[MinMax(-180, 180)] public Int32 StereoPanningAngle = 15;
+ [MinMax(1, 100)] public Int32 StereoCombFilterDelay = 5;
+ [MinMax(1, 200)] public Int32 StereoCombFilterStrength = 100;
+
public bool ReverbEnabled = false;
[MinMax(1, 10)] public UInt32 ReverbStrength = 5;
[MinMax(1, 30)] public UInt32 ReverbDelay = 10;
+
public bool CrossFeedEnabled = false;
[MinMax(0, 100)] public UInt32 CrossFeedRatio = 0;
@@ -183,21 +187,15 @@ namespace Mesen.GUI.Config
InteropEmu.SetFlag(EmulationFlags.ReduceDmcPopping, audioInfo.ReduceDmcPopping);
InteropEmu.SetFlag(EmulationFlags.DisableNoiseModeFlag, audioInfo.DisableNoiseModeFlag);
- InteropEmu.SetStereoFilter(audioInfo.StereoFilter);
- InteropEmu.SetStereoPanningAngle((double)audioInfo.StereoPanningAngle/180*Math.PI);
- InteropEmu.SetStereoDelay(audioInfo.StereoDelay);
-
- if(audioInfo.ReverbEnabled) {
- InteropEmu.SetReverbParameters(audioInfo.ReverbStrength/10.0, audioInfo.ReverbDelay/10.0);
- } else {
- InteropEmu.SetReverbParameters(0, 0);
- }
-
- if(audioInfo.CrossFeedEnabled) {
- InteropEmu.SetCrossFeedRatio(audioInfo.CrossFeedRatio);
- } else {
- InteropEmu.SetCrossFeedRatio(0);
- }
+ InteropEmu.SetAudioFilterSettings(new InteropEmu.AudioFilterSettings() {
+ StereoFilter = audioInfo.StereoFilter,
+ Angle = (double)audioInfo.StereoPanningAngle / 180 * Math.PI,
+ Delay = audioInfo.StereoFilter == InteropEmu.StereoFilter.Delay ? audioInfo.StereoDelay : audioInfo.StereoCombFilterDelay,
+ Strength = audioInfo.StereoCombFilterStrength,
+ ReverbDelay = audioInfo.ReverbEnabled ? audioInfo.ReverbDelay / 10.0 : 0,
+ ReverbStrength = audioInfo.ReverbEnabled ? audioInfo.ReverbStrength / 10.0 : 0,
+ CrossFeedRatio = audioInfo.CrossFeedEnabled ? (int)audioInfo.CrossFeedRatio : 0
+ });
}
}
diff --git a/GUI.NET/Dependencies/resources.ca.xml b/GUI.NET/Dependencies/resources.ca.xml
index 06bf06b0..76c33132 100644
--- a/GUI.NET/Dependencies/resources.ca.xml
+++ b/GUI.NET/Dependencies/resources.ca.xml
@@ -135,6 +135,10 @@
Panoràmic
ms
(angle en graus)
+ Comb Filter
+ ms
+ Retard:
+ Força:
Activa la mescla de canals:
Reverberació
Activa la reverberació
diff --git a/GUI.NET/Dependencies/resources.en.xml b/GUI.NET/Dependencies/resources.en.xml
index 78903b30..19587535 100644
--- a/GUI.NET/Dependencies/resources.en.xml
+++ b/GUI.NET/Dependencies/resources.en.xml
@@ -135,6 +135,10 @@
Panning
ms
(Angle in degrees)
+ Comb Filter
+ ms
+ Delay:
+ Strength:
Enable Crossfeed:
Reverb
Enable Reverb
diff --git a/GUI.NET/Dependencies/resources.es.xml b/GUI.NET/Dependencies/resources.es.xml
index 251c5c37..8a13afe5 100644
--- a/GUI.NET/Dependencies/resources.es.xml
+++ b/GUI.NET/Dependencies/resources.es.xml
@@ -134,6 +134,10 @@
Panorámico
ms
(Ángulo en grados)
+ Comb Filter
+ ms
+ Retraso:
+ Fuerza:
Activar mezcla de canales:
Reverberación
Activar la reverberación
diff --git a/GUI.NET/Dependencies/resources.fr.xml b/GUI.NET/Dependencies/resources.fr.xml
index f4814b79..7309df6e 100644
--- a/GUI.NET/Dependencies/resources.fr.xml
+++ b/GUI.NET/Dependencies/resources.fr.xml
@@ -135,6 +135,10 @@
Panoramique
ms
(angle en degrés)
+ Filtre en peigne
+ ms
+ Délai :
+ Force :
Activer le crossfeed :
Réverbération
Activer la réverbération
diff --git a/GUI.NET/Dependencies/resources.ja.xml b/GUI.NET/Dependencies/resources.ja.xml
index 48d552ff..b6f42c16 100644
--- a/GUI.NET/Dependencies/resources.ja.xml
+++ b/GUI.NET/Dependencies/resources.ja.xml
@@ -136,6 +136,10 @@
パニング
ミリ秒
(角度)
+ コムフィルタ
+ ミリ秒
+ ディレイ:
+ 強度:
クロスフィード:
残響
残響を有効にする
diff --git a/GUI.NET/Dependencies/resources.pt.xml b/GUI.NET/Dependencies/resources.pt.xml
index 8095a8f1..a9a4e125 100644
--- a/GUI.NET/Dependencies/resources.pt.xml
+++ b/GUI.NET/Dependencies/resources.pt.xml
@@ -134,6 +134,10 @@
Panorâmico
ms
(Ângulo em graus)
+ Comb Filter
+ ms
+ Atraso:
+ Força:
Ativar mistura de canais
Ressonância
Ativar a ressonância
diff --git a/GUI.NET/Dependencies/resources.ru.xml b/GUI.NET/Dependencies/resources.ru.xml
index 1aeb8960..415bbbba 100644
--- a/GUI.NET/Dependencies/resources.ru.xml
+++ b/GUI.NET/Dependencies/resources.ru.xml
@@ -134,6 +134,10 @@
Панорамирование
мс
угол в градусах
+ Comb Filter
+ мс
+ Задержка :
+ Сила :
Enable Crossfeed:
Реверберация
Включена
diff --git a/GUI.NET/Dependencies/resources.uk.xml b/GUI.NET/Dependencies/resources.uk.xml
index 991089ee..273bddf7 100644
--- a/GUI.NET/Dependencies/resources.uk.xml
+++ b/GUI.NET/Dependencies/resources.uk.xml
@@ -134,6 +134,10 @@
Панорамування
мс
кут в градусах
+ Comb Filter
+ мс
+ Затримка :
+ Сила :
Включити кільцювання:
Відлуння
Включена
diff --git a/GUI.NET/Forms/Config/frmAudioConfig.Designer.cs b/GUI.NET/Forms/Config/frmAudioConfig.Designer.cs
index 06f54653..64bb96bc 100644
--- a/GUI.NET/Forms/Config/frmAudioConfig.Designer.cs
+++ b/GUI.NET/Forms/Config/frmAudioConfig.Designer.cs
@@ -112,6 +112,7 @@ namespace Mesen.GUI.Forms.Config
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
this.grpStereo = new System.Windows.Forms.GroupBox();
this.tlpStereoFilter = new System.Windows.Forms.TableLayoutPanel();
+ this.radStereoCombFilter = new System.Windows.Forms.RadioButton();
this.lblStereoDelayMs = new System.Windows.Forms.Label();
this.lblStereoPanningAngle = new System.Windows.Forms.Label();
this.radStereoDisabled = new System.Windows.Forms.RadioButton();
@@ -119,6 +120,13 @@ namespace Mesen.GUI.Forms.Config
this.radStereoPanning = new System.Windows.Forms.RadioButton();
this.nudStereoDelay = new Mesen.GUI.Controls.MesenNumericUpDown();
this.nudStereoPanning = new Mesen.GUI.Controls.MesenNumericUpDown();
+ this.tableLayoutPanel9 = new System.Windows.Forms.TableLayoutPanel();
+ this.nudStereoCombFilterStrength = new Mesen.GUI.Controls.MesenNumericUpDown();
+ this.lblStereoCombFilterMs = new System.Windows.Forms.Label();
+ this.nudStereoCombFilterDelay = new Mesen.GUI.Controls.MesenNumericUpDown();
+ this.lblStereoCombFilterDelay = new System.Windows.Forms.Label();
+ this.lblStereoCombFilterStrength = new System.Windows.Forms.Label();
+ this.lblCombFilterPercent = new System.Windows.Forms.Label();
this.grpReverb = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel5 = new System.Windows.Forms.TableLayoutPanel();
this.chkReverbEnabled = new System.Windows.Forms.CheckBox();
@@ -132,11 +140,11 @@ namespace Mesen.GUI.Forms.Config
this.lblCrossFeedRatio = new System.Windows.Forms.Label();
this.tpgAdvanced = new System.Windows.Forms.TabPage();
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
+ this.chkDisableDynamicSampleRate = new Mesen.GUI.Controls.ctrlRiskyOption();
this.chkDisableNoiseModeFlag = new Mesen.GUI.Controls.ctrlRiskyOption();
this.chkSilenceTriangleHighFreq = new System.Windows.Forms.CheckBox();
this.chkSwapDutyCycles = new Mesen.GUI.Controls.ctrlRiskyOption();
this.chkReduceDmcPopping = new System.Windows.Forms.CheckBox();
- this.chkDisableDynamicSampleRate = new Mesen.GUI.Controls.ctrlRiskyOption();
this.baseConfigPanel.SuspendLayout();
this.grpVolume.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
@@ -158,6 +166,7 @@ namespace Mesen.GUI.Forms.Config
this.tableLayoutPanel4.SuspendLayout();
this.grpStereo.SuspendLayout();
this.tlpStereoFilter.SuspendLayout();
+ this.tableLayoutPanel9.SuspendLayout();
this.grpReverb.SuspendLayout();
this.tableLayoutPanel5.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.trkReverbDelay)).BeginInit();
@@ -1425,7 +1434,7 @@ namespace Mesen.GUI.Forms.Config
this.grpStereo.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpStereo.Location = new System.Drawing.Point(3, 3);
this.grpStereo.Name = "grpStereo";
- this.grpStereo.Size = new System.Drawing.Size(457, 95);
+ this.grpStereo.Size = new System.Drawing.Size(457, 115);
this.grpStereo.TabIndex = 0;
this.grpStereo.TabStop = false;
this.grpStereo.Text = "Stereo";
@@ -1436,6 +1445,7 @@ namespace Mesen.GUI.Forms.Config
this.tlpStereoFilter.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpStereoFilter.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpStereoFilter.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tlpStereoFilter.Controls.Add(this.radStereoCombFilter, 0, 3);
this.tlpStereoFilter.Controls.Add(this.lblStereoDelayMs, 2, 1);
this.tlpStereoFilter.Controls.Add(this.lblStereoPanningAngle, 2, 2);
this.tlpStereoFilter.Controls.Add(this.radStereoDisabled, 0, 0);
@@ -1443,22 +1453,36 @@ namespace Mesen.GUI.Forms.Config
this.tlpStereoFilter.Controls.Add(this.radStereoPanning, 0, 2);
this.tlpStereoFilter.Controls.Add(this.nudStereoDelay, 1, 1);
this.tlpStereoFilter.Controls.Add(this.nudStereoPanning, 1, 2);
+ this.tlpStereoFilter.Controls.Add(this.tableLayoutPanel9, 1, 3);
this.tlpStereoFilter.Dock = System.Windows.Forms.DockStyle.Fill;
this.tlpStereoFilter.Location = new System.Drawing.Point(3, 16);
this.tlpStereoFilter.Name = "tlpStereoFilter";
- this.tlpStereoFilter.RowCount = 4;
+ this.tlpStereoFilter.RowCount = 5;
+ this.tlpStereoFilter.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpStereoFilter.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpStereoFilter.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpStereoFilter.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpStereoFilter.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
- this.tlpStereoFilter.Size = new System.Drawing.Size(451, 76);
+ this.tlpStereoFilter.Size = new System.Drawing.Size(451, 96);
this.tlpStereoFilter.TabIndex = 0;
//
+ // radStereoCombFilter
+ //
+ this.radStereoCombFilter.AutoSize = true;
+ this.radStereoCombFilter.Location = new System.Drawing.Point(3, 72);
+ this.radStereoCombFilter.Name = "radStereoCombFilter";
+ this.radStereoCombFilter.Size = new System.Drawing.Size(77, 17);
+ this.radStereoCombFilter.TabIndex = 4;
+ this.radStereoCombFilter.TabStop = true;
+ this.radStereoCombFilter.Tag = "Panning";
+ this.radStereoCombFilter.Text = "Comb Filter";
+ this.radStereoCombFilter.UseVisualStyleBackColor = true;
+ //
// lblStereoDelayMs
//
this.lblStereoDelayMs.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblStereoDelayMs.AutoSize = true;
- this.lblStereoDelayMs.Location = new System.Drawing.Point(120, 28);
+ this.lblStereoDelayMs.Location = new System.Drawing.Point(131, 28);
this.lblStereoDelayMs.Name = "lblStereoDelayMs";
this.lblStereoDelayMs.Size = new System.Drawing.Size(20, 13);
this.lblStereoDelayMs.TabIndex = 1;
@@ -1468,7 +1492,7 @@ namespace Mesen.GUI.Forms.Config
//
this.lblStereoPanningAngle.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblStereoPanningAngle.AutoSize = true;
- this.lblStereoPanningAngle.Location = new System.Drawing.Point(120, 51);
+ this.lblStereoPanningAngle.Location = new System.Drawing.Point(131, 51);
this.lblStereoPanningAngle.Name = "lblStereoPanningAngle";
this.lblStereoPanningAngle.Size = new System.Drawing.Size(92, 13);
this.lblStereoPanningAngle.TabIndex = 1;
@@ -1520,7 +1544,7 @@ namespace Mesen.GUI.Forms.Config
0,
0,
0});
- this.nudStereoDelay.Location = new System.Drawing.Point(72, 24);
+ this.nudStereoDelay.Location = new System.Drawing.Point(83, 24);
this.nudStereoDelay.Margin = new System.Windows.Forms.Padding(0);
this.nudStereoDelay.Maximum = new decimal(new int[] {
100,
@@ -1552,7 +1576,7 @@ namespace Mesen.GUI.Forms.Config
0,
0,
0});
- this.nudStereoPanning.Location = new System.Drawing.Point(72, 47);
+ this.nudStereoPanning.Location = new System.Drawing.Point(83, 47);
this.nudStereoPanning.Margin = new System.Windows.Forms.Padding(0);
this.nudStereoPanning.Maximum = new decimal(new int[] {
180,
@@ -1574,12 +1598,143 @@ namespace Mesen.GUI.Forms.Config
0,
0,
0});
+ //
+ // tableLayoutPanel9
+ //
+ this.tableLayoutPanel9.ColumnCount = 7;
+ this.tlpStereoFilter.SetColumnSpan(this.tableLayoutPanel9, 2);
+ this.tableLayoutPanel9.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.tableLayoutPanel9.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.tableLayoutPanel9.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.tableLayoutPanel9.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.tableLayoutPanel9.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.tableLayoutPanel9.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.tableLayoutPanel9.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel9.Controls.Add(this.nudStereoCombFilterStrength, 4, 0);
+ this.tableLayoutPanel9.Controls.Add(this.lblStereoCombFilterMs, 2, 0);
+ this.tableLayoutPanel9.Controls.Add(this.nudStereoCombFilterDelay, 1, 0);
+ this.tableLayoutPanel9.Controls.Add(this.lblStereoCombFilterDelay, 0, 0);
+ this.tableLayoutPanel9.Controls.Add(this.lblStereoCombFilterStrength, 3, 0);
+ this.tableLayoutPanel9.Controls.Add(this.lblCombFilterPercent, 5, 0);
+ this.tableLayoutPanel9.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tableLayoutPanel9.Location = new System.Drawing.Point(83, 69);
+ this.tableLayoutPanel9.Margin = new System.Windows.Forms.Padding(0);
+ this.tableLayoutPanel9.Name = "tableLayoutPanel9";
+ this.tableLayoutPanel9.RowCount = 1;
+ this.tableLayoutPanel9.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel9.Size = new System.Drawing.Size(368, 23);
+ this.tableLayoutPanel9.TabIndex = 5;
+ //
+ // nudStereoCombFilterStrength
+ //
+ this.nudStereoCombFilterStrength.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.nudStereoCombFilterStrength.DecimalPlaces = 0;
+ this.nudStereoCombFilterStrength.Increment = new decimal(new int[] {
+ 1,
+ 0,
+ 0,
+ 0});
+ this.nudStereoCombFilterStrength.Location = new System.Drawing.Point(187, 1);
+ this.nudStereoCombFilterStrength.Margin = new System.Windows.Forms.Padding(0);
+ this.nudStereoCombFilterStrength.Maximum = new decimal(new int[] {
+ 200,
+ 0,
+ 0,
+ 0});
+ this.nudStereoCombFilterStrength.MaximumSize = new System.Drawing.Size(10000, 20);
+ this.nudStereoCombFilterStrength.Minimum = new decimal(new int[] {
+ 1,
+ 0,
+ 0,
+ 0});
+ this.nudStereoCombFilterStrength.MinimumSize = new System.Drawing.Size(0, 21);
+ this.nudStereoCombFilterStrength.Name = "nudStereoCombFilterStrength";
+ this.nudStereoCombFilterStrength.Size = new System.Drawing.Size(45, 21);
+ this.nudStereoCombFilterStrength.TabIndex = 5;
+ this.nudStereoCombFilterStrength.Value = new decimal(new int[] {
+ 1,
+ 0,
+ 0,
+ 0});
+ //
+ // lblStereoCombFilterMs
+ //
+ this.lblStereoCombFilterMs.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.lblStereoCombFilterMs.AutoSize = true;
+ this.lblStereoCombFilterMs.Location = new System.Drawing.Point(91, 5);
+ this.lblStereoCombFilterMs.Name = "lblStereoCombFilterMs";
+ this.lblStereoCombFilterMs.Size = new System.Drawing.Size(20, 13);
+ this.lblStereoCombFilterMs.TabIndex = 3;
+ this.lblStereoCombFilterMs.Text = "ms";
+ //
+ // nudStereoCombFilterDelay
+ //
+ this.nudStereoCombFilterDelay.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.nudStereoCombFilterDelay.DecimalPlaces = 0;
+ this.nudStereoCombFilterDelay.Increment = new decimal(new int[] {
+ 1,
+ 0,
+ 0,
+ 0});
+ this.nudStereoCombFilterDelay.Location = new System.Drawing.Point(43, 1);
+ this.nudStereoCombFilterDelay.Margin = new System.Windows.Forms.Padding(0);
+ this.nudStereoCombFilterDelay.Maximum = new decimal(new int[] {
+ 100,
+ 0,
+ 0,
+ 0});
+ this.nudStereoCombFilterDelay.MaximumSize = new System.Drawing.Size(10000, 20);
+ this.nudStereoCombFilterDelay.Minimum = new decimal(new int[] {
+ 1,
+ 0,
+ 0,
+ 0});
+ this.nudStereoCombFilterDelay.MinimumSize = new System.Drawing.Size(0, 21);
+ this.nudStereoCombFilterDelay.Name = "nudStereoCombFilterDelay";
+ this.nudStereoCombFilterDelay.Size = new System.Drawing.Size(45, 21);
+ this.nudStereoCombFilterDelay.TabIndex = 2;
+ this.nudStereoCombFilterDelay.Value = new decimal(new int[] {
+ 1,
+ 0,
+ 0,
+ 0});
+ //
+ // lblStereoCombFilterDelay
+ //
+ this.lblStereoCombFilterDelay.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.lblStereoCombFilterDelay.AutoSize = true;
+ this.lblStereoCombFilterDelay.Location = new System.Drawing.Point(3, 5);
+ this.lblStereoCombFilterDelay.Name = "lblStereoCombFilterDelay";
+ this.lblStereoCombFilterDelay.Size = new System.Drawing.Size(37, 13);
+ this.lblStereoCombFilterDelay.TabIndex = 0;
+ this.lblStereoCombFilterDelay.Text = "Delay:";
+ //
+ // lblStereoCombFilterStrength
+ //
+ this.lblStereoCombFilterStrength.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.lblStereoCombFilterStrength.AutoSize = true;
+ this.lblStereoCombFilterStrength.Location = new System.Drawing.Point(134, 5);
+ this.lblStereoCombFilterStrength.Margin = new System.Windows.Forms.Padding(20, 0, 3, 0);
+ this.lblStereoCombFilterStrength.Name = "lblStereoCombFilterStrength";
+ this.lblStereoCombFilterStrength.Size = new System.Drawing.Size(50, 13);
+ this.lblStereoCombFilterStrength.TabIndex = 4;
+ this.lblStereoCombFilterStrength.Text = "Strength:";
+ //
+ // lblCombFilterPercent
+ //
+ this.lblCombFilterPercent.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.lblCombFilterPercent.AutoSize = true;
+ this.lblCombFilterPercent.Location = new System.Drawing.Point(235, 5);
+ this.lblCombFilterPercent.Name = "lblCombFilterPercent";
+ this.lblCombFilterPercent.Size = new System.Drawing.Size(15, 13);
+ this.lblCombFilterPercent.TabIndex = 6;
+ this.lblCombFilterPercent.Text = "%";
//
// grpReverb
//
this.grpReverb.Controls.Add(this.tableLayoutPanel5);
this.grpReverb.Dock = System.Windows.Forms.DockStyle.Fill;
- this.grpReverb.Location = new System.Drawing.Point(3, 104);
+ this.grpReverb.Location = new System.Drawing.Point(3, 124);
this.grpReverb.Name = "grpReverb";
this.grpReverb.Size = new System.Drawing.Size(457, 106);
this.grpReverb.TabIndex = 1;
@@ -1665,7 +1820,7 @@ namespace Mesen.GUI.Forms.Config
this.flowLayoutPanel5.Controls.Add(this.nudCrossFeedRatio);
this.flowLayoutPanel5.Controls.Add(this.lblCrossFeedRatio);
this.flowLayoutPanel5.Dock = System.Windows.Forms.DockStyle.Fill;
- this.flowLayoutPanel5.Location = new System.Drawing.Point(6, 213);
+ this.flowLayoutPanel5.Location = new System.Drawing.Point(6, 233);
this.flowLayoutPanel5.Margin = new System.Windows.Forms.Padding(6, 0, 0, 0);
this.flowLayoutPanel5.Name = "flowLayoutPanel5";
this.flowLayoutPanel5.Size = new System.Drawing.Size(457, 25);
@@ -1758,6 +1913,16 @@ namespace Mesen.GUI.Forms.Config
this.tableLayoutPanel3.Size = new System.Drawing.Size(463, 341);
this.tableLayoutPanel3.TabIndex = 1;
//
+ // chkDisableDynamicSampleRate
+ //
+ this.chkDisableDynamicSampleRate.Checked = false;
+ this.chkDisableDynamicSampleRate.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.chkDisableDynamicSampleRate.Location = new System.Drawing.Point(0, 48);
+ this.chkDisableDynamicSampleRate.Name = "chkDisableDynamicSampleRate";
+ this.chkDisableDynamicSampleRate.Size = new System.Drawing.Size(463, 24);
+ this.chkDisableDynamicSampleRate.TabIndex = 4;
+ this.chkDisableDynamicSampleRate.Text = "Disable dynamic sample rate";
+ //
// chkDisableNoiseModeFlag
//
this.chkDisableNoiseModeFlag.Checked = false;
@@ -1799,16 +1964,6 @@ namespace Mesen.GUI.Forms.Config
this.chkReduceDmcPopping.TextAlign = System.Drawing.ContentAlignment.TopLeft;
this.chkReduceDmcPopping.UseVisualStyleBackColor = true;
//
- // chkDisableDynamicSampleRate
- //
- this.chkDisableDynamicSampleRate.Checked = false;
- this.chkDisableDynamicSampleRate.Dock = System.Windows.Forms.DockStyle.Fill;
- this.chkDisableDynamicSampleRate.Location = new System.Drawing.Point(0, 48);
- this.chkDisableDynamicSampleRate.Name = "chkDisableDynamicSampleRate";
- this.chkDisableDynamicSampleRate.Size = new System.Drawing.Size(463, 24);
- this.chkDisableDynamicSampleRate.TabIndex = 4;
- this.chkDisableDynamicSampleRate.Text = "Disable dynamic sample rate";
- //
// frmAudioConfig
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -1854,6 +2009,8 @@ namespace Mesen.GUI.Forms.Config
this.grpStereo.ResumeLayout(false);
this.tlpStereoFilter.ResumeLayout(false);
this.tlpStereoFilter.PerformLayout();
+ this.tableLayoutPanel9.ResumeLayout(false);
+ this.tableLayoutPanel9.PerformLayout();
this.grpReverb.ResumeLayout(false);
this.tableLayoutPanel5.ResumeLayout(false);
this.tableLayoutPanel5.PerformLayout();
@@ -1978,5 +2135,13 @@ namespace Mesen.GUI.Forms.Config
private ctrlHorizontalTrackbar trkVolumeReduction;
private System.Windows.Forms.CheckBox chkMuteSoundInBackground;
private ctrlRiskyOption chkDisableDynamicSampleRate;
+ private System.Windows.Forms.RadioButton radStereoCombFilter;
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel9;
+ private MesenNumericUpDown nudStereoCombFilterStrength;
+ private System.Windows.Forms.Label lblStereoCombFilterMs;
+ private MesenNumericUpDown nudStereoCombFilterDelay;
+ private System.Windows.Forms.Label lblStereoCombFilterDelay;
+ private System.Windows.Forms.Label lblStereoCombFilterStrength;
+ private System.Windows.Forms.Label lblCombFilterPercent;
}
}
\ No newline at end of file
diff --git a/GUI.NET/Forms/Config/frmAudioConfig.cs b/GUI.NET/Forms/Config/frmAudioConfig.cs
index 2d51b7c4..7045cc97 100644
--- a/GUI.NET/Forms/Config/frmAudioConfig.cs
+++ b/GUI.NET/Forms/Config/frmAudioConfig.cs
@@ -101,10 +101,13 @@ namespace Mesen.GUI.Forms.Config
radStereoDisabled.Tag = InteropEmu.StereoFilter.None;
radStereoDelay.Tag = InteropEmu.StereoFilter.Delay;
radStereoPanning.Tag = InteropEmu.StereoFilter.Panning;
+ radStereoCombFilter.Tag = InteropEmu.StereoFilter.CombFilter;
AddBinding("StereoFilter", tlpStereoFilter);
AddBinding("StereoDelay", nudStereoDelay);
AddBinding("StereoPanningAngle", nudStereoPanning);
+ AddBinding("StereoCombFilterDelay", nudStereoCombFilterDelay);
+ AddBinding("StereoCombFilterStrength", nudStereoCombFilterStrength);
AddBinding("ReverbEnabled", chkReverbEnabled);
AddBinding("ReverbDelay", trkReverbDelay);
diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs
index 6b9c1ecf..f17d23bc 100644
--- a/GUI.NET/InteropEmu.cs
+++ b/GUI.NET/InteropEmu.cs
@@ -184,11 +184,7 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void SetBandGain(int band, double gain);
[DllImport(DLLPath)] public static extern void SetSampleRate(UInt32 sampleRate);
[DllImport(DLLPath)] public static extern void SetAudioLatency(UInt32 msLatency);
- [DllImport(DLLPath)] public static extern void SetStereoFilter(StereoFilter stereoFilter);
- [DllImport(DLLPath)] public static extern void SetStereoDelay(Int32 delay);
- [DllImport(DLLPath)] public static extern void SetStereoPanningAngle(double angle);
- [DllImport(DLLPath)] public static extern void SetReverbParameters(double strength, double delay);
- [DllImport(DLLPath)] public static extern void SetCrossFeedRatio(UInt32 ratio);
+ [DllImport(DLLPath)] public static extern void SetAudioFilterSettings(AudioFilterSettings settings);
[DllImport(DLLPath)] public static extern NesModel GetNesModel();
[DllImport(DLLPath)] public static extern void SetNesModel(NesModel model);
@@ -1051,6 +1047,20 @@ namespace Mesen.GUI
None = 0,
Delay = 1,
Panning = 2,
+ CombFilter = 3,
+ }
+
+ public struct AudioFilterSettings
+ {
+ public StereoFilter StereoFilter;
+ public double Angle;
+ public Int32 Delay;
+ public Int32 Strength;
+
+ public double ReverbDelay;
+ public double ReverbStrength;
+
+ public Int32 CrossFeedRatio;
}
public struct ScreenSize
diff --git a/InteropDLL/ConsoleWrapper.cpp b/InteropDLL/ConsoleWrapper.cpp
index 13203c33..3d72c00f 100644
--- a/InteropDLL/ConsoleWrapper.cpp
+++ b/InteropDLL/ConsoleWrapper.cpp
@@ -607,11 +607,7 @@ namespace InteropEmu {
DllExport void __stdcall SetMasterVolume(double volume, double volumeReduction, ConsoleId consoleId) { GetConsoleById(consoleId)->GetSettings()->SetMasterVolume(volume, volumeReduction); }
DllExport void __stdcall SetSampleRate(uint32_t sampleRate) { _settings->SetSampleRate(sampleRate); }
DllExport void __stdcall SetAudioLatency(uint32_t msLatency) { _settings->SetAudioLatency(msLatency); }
- DllExport void __stdcall SetStereoFilter(StereoFilter stereoFilter) { _settings->SetStereoFilter(stereoFilter); }
- DllExport void __stdcall SetStereoDelay(int32_t delay) { _settings->SetStereoDelay(delay); }
- DllExport void __stdcall SetStereoPanningAngle(double angle) { _settings->SetStereoPanningAngle(angle); }
- DllExport void __stdcall SetReverbParameters(double strength, double delay) { _settings->SetReverbParameters(strength, delay); }
- DllExport void __stdcall SetCrossFeedRatio(uint32_t ratio) { _settings->SetCrossFeedRatio(ratio); }
+ DllExport void __stdcall SetAudioFilterSettings(AudioFilterSettings settings) { _settings->SetAudioFilterSettings(settings); }
DllExport NesModel __stdcall GetNesModel() { return _console->GetModel(); }
DllExport void __stdcall SetNesModel(uint32_t model) { _settings->SetNesModel((NesModel)model); }