Audio: Added comb filter stereo effect

This commit is contained in:
Sour 2018-08-03 10:49:23 -04:00
parent 80afa1ab00
commit 781650e8bf
22 changed files with 332 additions and 115 deletions

View file

@ -561,6 +561,7 @@
<ClInclude Include="Sachen9602.h" />
<ClInclude Include="ServerInformationMessage.h" />
<ClInclude Include="FamicomBox.h" />
<ClInclude Include="StereoCombFilter.h" />
<ClInclude Include="SystemActionManager.h" />
<ClInclude Include="DatachBarcodeReader.h" />
<ClInclude Include="DebugHud.h" />
@ -1050,6 +1051,7 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='PGO Profile|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="StereoCombFilter.cpp" />
<ClCompile Include="StereoDelayFilter.cpp" />
<ClCompile Include="StereoPanningFilter.cpp" />
<ClCompile Include="TraceLogger.cpp" />

View file

@ -1471,6 +1471,9 @@
<ClInclude Include="HistoryViewer.h">
<Filter>Rewinder</Filter>
</ClInclude>
<ClInclude Include="StereoCombFilter.h">
<Filter>Nes\APU\Filters</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
@ -1761,5 +1764,8 @@
<ClCompile Include="HistoryViewer.cpp">
<Filter>Rewinder</Filter>
</ClCompile>
<ClCompile Include="StereoCombFilter.cpp">
<Filter>Nes\APU\Filters</Filter>
</ClCompile>
</ItemGroup>
</Project>

View file

@ -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)
{

View file

@ -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)) {

View file

@ -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;

29
Core/StereoCombFilter.cpp Normal file
View file

@ -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();
}
}

13
Core/StereoCombFilter.h Normal file
View file

@ -0,0 +1,13 @@
#pragma once
#include "stdafx.h"
#include <deque>
class StereoCombFilter
{
std::deque<int16_t> _delayedSamplesLeft;
std::deque<int16_t> _delayedSamplesRight;
size_t _lastDelay = 0;
public:
void ApplyFilter(int16_t* stereoBuffer, size_t sampleCount, uint32_t sampleRate, int32_t delay, uint32_t strength);
};

View file

@ -1,4 +1,5 @@
#include "stdafx.h"
#include <algorithm>
#include "StereoDelayFilter.h"
void StereoDelayFilter::ApplyFilter(int16_t* stereoBuffer, size_t sampleCount, uint32_t sampleRate, int32_t stereoDelay)

View file

@ -1,8 +1,6 @@
#pragma once
#include "stdafx.h"
#include <deque>
#include <algorithm>
#include "EmulationSettings.h"
class StereoDelayFilter
{

View file

@ -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
});
}
}

View file

@ -135,6 +135,10 @@
<Control ID="radStereoPanning">Panoràmic</Control>
<Control ID="lblStereoDelayMs">ms</Control>
<Control ID="lblStereoPanningAngle">(angle en graus)</Control>
<Control ID="radStereoCombFilter">Comb Filter</Control>
<Control ID="lblStereoCombFilterMs">ms</Control>
<Control ID="lblStereoCombFilterDelay">Retard:</Control>
<Control ID="lblStereoCombFilterStrength">Força:</Control>
<Control ID="chkCrossFeedEnabled">Activa la mescla de canals:</Control>
<Control ID="grpReverb">Reverberació</Control>
<Control ID="chkReverbEnabled">Activa la reverberació</Control>

View file

@ -135,6 +135,10 @@
<Control ID="radStereoPanning">Panning</Control>
<Control ID="lblStereoDelayMs">ms</Control>
<Control ID="lblStereoPanningAngle">(Angle in degrees)</Control>
<Control ID="radStereoCombFilter">Comb Filter</Control>
<Control ID="lblStereoCombFilterMs">ms</Control>
<Control ID="lblStereoCombFilterDelay">Delay:</Control>
<Control ID="lblStereoCombFilterStrength">Strength:</Control>
<Control ID="chkCrossFeedEnabled">Enable Crossfeed:</Control>
<Control ID="grpReverb">Reverb</Control>
<Control ID="chkReverbEnabled">Enable Reverb</Control>

View file

@ -134,6 +134,10 @@
<Control ID="radStereoPanning">Panorámico</Control>
<Control ID="lblStereoDelayMs">ms</Control>
<Control ID="lblStereoPanningAngle">(Ángulo en grados)</Control>
<Control ID="radStereoCombFilter">Comb Filter</Control>
<Control ID="lblStereoCombFilterMs">ms</Control>
<Control ID="lblStereoCombFilterDelay">Retraso:</Control>
<Control ID="lblStereoCombFilterStrength">Fuerza:</Control>
<Control ID="chkCrossFeedEnabled">Activar mezcla de canales:</Control>
<Control ID="grpReverb">Reverberación</Control>
<Control ID="chkReverbEnabled">Activar la reverberación</Control>

View file

@ -135,6 +135,10 @@
<Control ID="radStereoPanning">Panoramique</Control>
<Control ID="lblStereoDelayMs">ms</Control>
<Control ID="lblStereoPanningAngle">(angle en degrés)</Control>
<Control ID="radStereoCombFilter">Filtre en peigne</Control>
<Control ID="lblStereoCombFilterMs">ms</Control>
<Control ID="lblStereoCombFilterDelay">Délai :</Control>
<Control ID="lblStereoCombFilterStrength">Force :</Control>
<Control ID="chkCrossFeedEnabled">Activer le crossfeed :</Control>
<Control ID="grpReverb">Réverbération</Control>
<Control ID="chkReverbEnabled">Activer la réverbération</Control>

View file

@ -136,6 +136,10 @@
<Control ID="radStereoPanning">パニング</Control>
<Control ID="lblStereoDelayMs">ミリ秒</Control>
<Control ID="lblStereoPanningAngle">(角度)</Control>
<Control ID="radStereoCombFilter">コムフィルタ</Control>
<Control ID="lblStereoCombFilterMs">ミリ秒</Control>
<Control ID="lblStereoCombFilterDelay">ディレイ:</Control>
<Control ID="lblStereoCombFilterStrength">強度:</Control>
<Control ID="chkCrossFeedEnabled">クロスフィード:</Control>
<Control ID="grpReverb">残響</Control>
<Control ID="chkReverbEnabled">残響を有効にする</Control>

View file

@ -134,6 +134,10 @@
<Control ID="radStereoPanning">Panorâmico</Control>
<Control ID="lblStereoDelayMs">ms</Control>
<Control ID="lblStereoPanningAngle">(Ângulo em graus)</Control>
<Control ID="radStereoCombFilter">Comb Filter</Control>
<Control ID="lblStereoCombFilterMs">ms</Control>
<Control ID="lblStereoCombFilterDelay">Atraso:</Control>
<Control ID="lblStereoCombFilterStrength">Força:</Control>
<Control ID="chkCrossFeedEnabled">Ativar mistura de canais</Control>
<Control ID="grpReverb">Ressonância</Control>
<Control ID="chkReverbEnabled">Ativar a ressonância</Control>

View file

@ -134,6 +134,10 @@
<Control ID="radStereoPanning">Панорамирование</Control>
<Control ID="lblStereoDelayMs">мс</Control>
<Control ID="lblStereoPanningAngle">угол в градусах</Control>
<Control ID="radStereoCombFilter">Comb Filter</Control>
<Control ID="lblStereoCombFilterMs">мс</Control>
<Control ID="lblStereoCombFilterDelay">Задержка :</Control>
<Control ID="lblStereoCombFilterStrength">Сила :</Control>
<Control ID="chkCrossFeedEnabled">Enable Crossfeed:</Control>
<Control ID="grpReverb">Реверберация</Control>
<Control ID="chkReverbEnabled">Включена</Control>

View file

@ -134,6 +134,10 @@
<Control ID="radStereoPanning">Панорамування</Control>
<Control ID="lblStereoDelayMs">мс</Control>
<Control ID="lblStereoPanningAngle">кут в градусах</Control>
<Control ID="radStereoCombFilter">Comb Filter</Control>
<Control ID="lblStereoCombFilterMs">мс</Control>
<Control ID="lblStereoCombFilterDelay">Затримка :</Control>
<Control ID="lblStereoCombFilterStrength">Сила :</Control>
<Control ID="chkCrossFeedEnabled">Включити кільцювання:</Control>
<Control ID="grpReverb">Відлуння</Control>
<Control ID="chkReverbEnabled">Включена</Control>

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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

View file

@ -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); }