Audio: Added stereo effects + reverb options

This commit is contained in:
Souryo 2016-02-21 15:31:39 -05:00
parent 5ce8b20fd1
commit d89cdfab01
25 changed files with 758 additions and 27 deletions

21
Core/BaseSoundFilter.cpp Normal file
View file

@ -0,0 +1,21 @@
#include "stdafx.h"
#include "BaseSoundFilter.h"
void BaseSoundFilter::UpdateBufferSize(size_t sampleCount, bool isStereo)
{
if(_maxSampleCount < sampleCount) {
if(_filterBuffer) {
delete[] _filterBuffer;
}
_maxSampleCount = sampleCount;
_filterBuffer = new int16_t[_maxSampleCount * (isStereo ? 2 : 1)];
memset(_filterBuffer, 0, _maxSampleCount * sizeof(int16_t) * (isStereo ? 2 : 1));
}
}
BaseSoundFilter::~BaseSoundFilter()
{
if(_filterBuffer) {
delete[] _filterBuffer;
}
}

14
Core/BaseSoundFilter.h Normal file
View file

@ -0,0 +1,14 @@
#pragma once
#include "stdafx.h"
class BaseSoundFilter
{
protected:
int16_t* _filterBuffer = nullptr;
size_t _maxSampleCount = 0;
void UpdateBufferSize(size_t sampleCount, bool isStereo);
public:
virtual ~BaseSoundFilter();
};

View file

@ -362,6 +362,7 @@
<ClInclude Include="Bandai74161_7432.h" />
<ClInclude Include="BaseFdsChannel.h" />
<ClInclude Include="BaseMapper.h" />
<ClInclude Include="BaseSoundFilter.h" />
<ClInclude Include="BF9096.h" />
<ClInclude Include="BF909x.h" />
<ClInclude Include="BnRom.h" />
@ -410,6 +411,7 @@
<ClInclude Include="MMC3_ChrRam.h" />
<ClInclude Include="ModChannel.h" />
<ClInclude Include="PlayerListMessage.h" />
<ClInclude Include="ReverbFilter.h" />
<ClInclude Include="RomData.h" />
<ClInclude Include="NtdecTc112.h" />
<ClInclude Include="Rambo1.h" />
@ -493,6 +495,8 @@
<ClInclude Include="MemoryManager.h" />
<ClInclude Include="RomLoader.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="StereoDelayFilter.h" />
<ClInclude Include="StereoPanningFilter.h" />
<ClInclude Include="Sunsoft184.h" />
<ClInclude Include="SunSoft3.h" />
<ClInclude Include="SunSoft4.h" />
@ -525,6 +529,7 @@
<ClCompile Include="AutoRomTest.cpp" />
<ClCompile Include="BaseControlDevice.cpp" />
<ClCompile Include="BaseMapper.cpp" />
<ClCompile Include="BaseSoundFilter.cpp" />
<ClCompile Include="Breakpoint.cpp" />
<ClCompile Include="CheatManager.cpp" />
<ClCompile Include="CodeDataLogger.cpp" />
@ -545,6 +550,7 @@
<ClCompile Include="GameServerConnection.cpp" />
<ClCompile Include="HdVideoFilter.cpp" />
<ClCompile Include="NtscFilter.cpp" />
<ClCompile Include="ReverbFilter.cpp" />
<ClCompile Include="RomLoader.cpp" />
<ClCompile Include="SoundMixer.cpp" />
<ClCompile Include="StandardController.cpp" />
@ -565,6 +571,8 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='PGO Profile|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='PGO Optimize|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="StereoDelayFilter.cpp" />
<ClCompile Include="StereoPanningFilter.cpp" />
<ClCompile Include="TraceLogger.cpp" />
<ClCompile Include="VideoRenderer.cpp" />
<ClCompile Include="VideoDecoder.cpp" />

View file

@ -66,6 +66,9 @@
<Filter Include="Nes\Controllers">
<UniqueIdentifier>{acd315c2-48ad-4243-a997-bb9a970c24bd}</UniqueIdentifier>
</Filter>
<Filter Include="Nes\APU\Filters">
<UniqueIdentifier>{783f3638-4293-480f-b525-2485c4209ff5}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
@ -551,6 +554,18 @@
<ClInclude Include="ArkanoidController.h">
<Filter>Nes\Controllers</Filter>
</ClInclude>
<ClInclude Include="StereoPanningFilter.h">
<Filter>Nes\APU\Filters</Filter>
</ClInclude>
<ClInclude Include="StereoDelayFilter.h">
<Filter>Nes\APU\Filters</Filter>
</ClInclude>
<ClInclude Include="ReverbFilter.h">
<Filter>Nes\APU\Filters</Filter>
</ClInclude>
<ClInclude Include="BaseSoundFilter.h">
<Filter>Nes\APU\Filters</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
@ -679,5 +694,17 @@
<ClCompile Include="ArkanoidController.cpp">
<Filter>Nes\Controllers</Filter>
</ClCompile>
<ClCompile Include="StereoPanningFilter.cpp">
<Filter>Nes\APU\Filters</Filter>
</ClCompile>
<ClCompile Include="StereoDelayFilter.cpp">
<Filter>Nes\APU\Filters</Filter>
</ClCompile>
<ClCompile Include="BaseSoundFilter.cpp">
<Filter>Nes\APU\Filters</Filter>
</ClCompile>
<ClCompile Include="ReverbFilter.cpp">
<Filter>Nes\APU\Filters</Filter>
</ClCompile>
</ItemGroup>
</Project>

View file

@ -30,6 +30,11 @@ uint32_t EmulationSettings::_audioLatency = 20000;
double EmulationSettings::_channelVolume[11] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
double EmulationSettings::_masterVolume = 1.0;
uint32_t EmulationSettings::_sampleRate = 44100;
StereoFilter EmulationSettings::_stereoFilter = StereoFilter::None;
int32_t EmulationSettings::_stereoDelay = 0;
double EmulationSettings::_stereoAngle = 0;
double EmulationSettings::_reverbStrength = 0;
double EmulationSettings::_reverbDelay = 0;
NesModel EmulationSettings::_model = NesModel::Auto;

View file

@ -152,6 +152,13 @@ enum class Language
Japanese = 3
};
enum class StereoFilter
{
None = 0,
Delay = 1,
Panning = 2,
};
class EmulationSettings
{
private:
@ -167,9 +174,13 @@ private:
static uint32_t _audioLatency;
static double _channelVolume[11];
static double _masterVolume;
static uint32_t _sampleRate;
static StereoFilter _stereoFilter;
static int32_t _stereoDelay;
static double _stereoAngle;
static double _reverbStrength;
static double _reverbDelay;
static NesModel _model;
static uint32_t _emulationSpeed;
@ -262,6 +273,52 @@ public:
_audioLatency = msLatency;
}
static void SetStereoFilter(StereoFilter stereoFilter)
{
_stereoFilter = stereoFilter;
}
static void SetStereoDelay(int32_t delay)
{
_stereoDelay = delay;
}
static void SetStereoPanningAngle(double angle)
{
_stereoAngle = angle;
}
static void SetReverbParameters(double strength, double delay)
{
_reverbStrength = strength;
_reverbDelay = delay;
}
static StereoFilter GetStereoFilter()
{
return _stereoFilter;
}
static int32_t GetStereoDelay()
{
return _stereoDelay;
}
static double GetStereoPanningAngle()
{
return _stereoAngle;
}
static double GetReverbStrength()
{
return _reverbStrength;
}
static double GetReverbDelay()
{
return _reverbDelay;
}
//0: No limit, Number: % of default speed (50/60fps)
static void SetEmulationSpeed(uint32_t emulationSpeed)
{

View file

@ -5,7 +5,7 @@
class IAudioDevice
{
public:
virtual void PlayBuffer(int16_t *soundBuffer, uint32_t bufferSize, uint32_t sampleRate) = 0;
virtual void PlayBuffer(int16_t *soundBuffer, uint32_t bufferSize, uint32_t sampleRate, bool isStereo) = 0;
virtual void Stop() = 0;
virtual void Pause() = 0;
};

31
Core/ReverbFilter.cpp Normal file
View file

@ -0,0 +1,31 @@
#include "stdafx.h"
#include "ReverbFilter.h"
void ReverbFilter::ResetFilter()
{
for(int i = 0; i < 5; i++) {
_delay[i].Reset();
}
}
int16_t* ReverbFilter::ApplyFilter(int16_t* monoBuffer, size_t sampleCount, uint32_t sampleRate, double reverbStrength, double reverbDelay)
{
_delay[0].SetParameters(550 * reverbDelay, 0.25 * reverbStrength, sampleRate);
_delay[1].SetParameters(330 * reverbDelay, 0.15 * reverbStrength, sampleRate);
_delay[2].SetParameters(485 * reverbDelay, 0.12 * reverbStrength, sampleRate);
_delay[3].SetParameters(150 * reverbDelay, 0.20 * reverbStrength, sampleRate);
_delay[4].SetParameters(285 * reverbDelay, 0.05 * reverbStrength, sampleRate);
UpdateBufferSize(sampleCount, false);
memcpy(_filterBuffer, monoBuffer, sampleCount * sizeof(int16_t));
for(int i = 0; i < 5; i++) {
_delay[i].ApplyReverb(_filterBuffer, sampleCount);
}
for(int i = 0; i < 5; i++) {
_delay[i].AddSamples(_filterBuffer, sampleCount);
}
return _filterBuffer;
}

57
Core/ReverbFilter.h Normal file
View file

@ -0,0 +1,57 @@
#pragma once
#include "stdafx.h"
#include "BaseSoundFilter.h"
#include <deque>
class ReverbDelay
{
private:
std::deque<int16_t> _samples;
uint32_t _delay = 0;
double _decay = 0;
public:
void SetParameters(double delay, double decay, int32_t sampleRate)
{
uint32_t delaySampleCount = (uint32_t)(delay / 1000 * sampleRate);
if(delaySampleCount != _delay || decay != _decay) {
_delay = delaySampleCount;
_decay = decay;
_samples.clear();
}
}
void Reset()
{
_samples.clear();
}
void AddSamples(int16_t* buffer, size_t sampleCount)
{
for(size_t i = 0; i < sampleCount; i++) {
_samples.push_back(buffer[i]);
}
}
void ApplyReverb(int16_t* buffer, size_t sampleCount)
{
if(_samples.size() > _delay) {
size_t samplesToInsert = std::min<size_t>(_samples.size() - _delay, sampleCount);
for(size_t j = sampleCount - samplesToInsert; j < sampleCount; j++) {
buffer[j] += (int16_t)((double)_samples.front() * _decay);
_samples.pop_front();
}
}
}
};
class ReverbFilter : public BaseSoundFilter
{
private:
ReverbDelay _delay[5];
public:
void ResetFilter();
int16_t* ApplyFilter(int16_t* monoBuffer, size_t sampleCount, uint32_t sampleRate, double reverbStrength, double reverbDelay);
};

View file

@ -82,9 +82,29 @@ void SoundMixer::PlayAudioBuffer(uint32_t time)
}
}
SoundMixer::AudioDevice->PlayBuffer(_outputBuffer, (uint32_t)(sampleCount * SoundMixer::BitsPerSample / 8), _sampleRate);
int16_t* soundBuffer = _outputBuffer;
if(EmulationSettings::GetReverbStrength() > 0) {
soundBuffer = _reverbFilter.ApplyFilter(soundBuffer, sampleCount, _sampleRate, EmulationSettings::GetReverbStrength(), EmulationSettings::GetReverbDelay());
} else {
_reverbFilter.ResetFilter();
}
bool isStereo = false;
switch(EmulationSettings::GetStereoFilter()) {
case StereoFilter::Delay:
soundBuffer = _stereoDelay.ApplyFilter(soundBuffer, sampleCount, _sampleRate);
isStereo = true;
break;
case StereoFilter::Panning:
soundBuffer = _stereoPanning.ApplyFilter(soundBuffer, sampleCount);
isStereo = true;
break;
}
SoundMixer::AudioDevice->PlayBuffer(soundBuffer, (uint32_t)sampleCount, _sampleRate, isStereo);
}
if(EmulationSettings::GetSampleRate() != _sampleRate) {
//Update sample rate for next frame if setting changed
_sampleRate = EmulationSettings::GetSampleRate();

View file

@ -5,6 +5,9 @@
#include "../BlipBuffer/blip_buf.h"
#include "IAudioDevice.h"
#include "Snapshotable.h"
#include "StereoPanningFilter.h"
#include "StereoDelayFilter.h"
#include "ReverbFilter.h"
class SoundMixer : public Snapshotable
{
@ -21,6 +24,9 @@ private:
AudioChannel _expansionAudioType;
LowPassFilter _lowPassFilter;
StereoPanningFilter _stereoPanning;
StereoDelayFilter _stereoDelay;
ReverbFilter _reverbFilter;
int16_t _previousOutput = 0;

View file

@ -0,0 +1,35 @@
#include "stdafx.h"
#include "StereoDelayFilter.h"
int16_t* StereoDelayFilter::ApplyFilter(int16_t* monoBuffer, size_t sampleCount, uint32_t sampleRate)
{
UpdateBufferSize(sampleCount, true);
int32_t delay = EmulationSettings::GetStereoDelay();
if(delay != _lastDelay) {
_delayedSamples.clear();
}
_lastDelay = delay;
int32_t delaySampleCount = (int32_t)((double)delay / 1000 * sampleRate);
for(size_t i = 0; i < sampleCount; i++) {
_delayedSamples.push_back(monoBuffer[i]);
}
for(int i = 0; i < sampleCount; i++) {
_filterBuffer[i * 2] = monoBuffer[i];
_filterBuffer[i * 2 + 1] = 0;
}
if(_delayedSamples.size() > delaySampleCount) {
size_t samplesToInsert = std::max<size_t>(_delayedSamples.size() - delaySampleCount, sampleCount);
for(size_t i = sampleCount - samplesToInsert; i < sampleCount; i++) {
_filterBuffer[i * 2 + 1] = _delayedSamples.front();
_delayedSamples.pop_front();
}
}
return _filterBuffer;
}

16
Core/StereoDelayFilter.h Normal file
View file

@ -0,0 +1,16 @@
#pragma once
#include "stdafx.h"
#include <deque>
#include <algorithm>
#include "EmulationSettings.h"
#include "BaseSoundFilter.h"
class StereoDelayFilter : public BaseSoundFilter
{
private:
std::deque<int16_t> _delayedSamples;
int32_t _lastDelay;
public:
int16_t* ApplyFilter(int16_t* monoBuffer, size_t sampleCount, uint32_t sampleRate);
};

View file

@ -0,0 +1,24 @@
#include "stdafx.h"
#include "StereoPanningFilter.h"
#include "EmulationSettings.h"
#include <cmath>
void StereoPanningFilter::UpdateFactors()
{
double angle = EmulationSettings::GetStereoPanningAngle();
_leftChannelFactor = _baseFactor * (std::cos(angle) - std::sin(angle));
_rightChannelFactor = _baseFactor * (std::cos(angle) + std::sin(angle));
}
int16_t* StereoPanningFilter::ApplyFilter(int16_t* monoBuffer, size_t sampleCount)
{
UpdateFactors();
UpdateBufferSize(sampleCount, true);
for(size_t i = 0; i < sampleCount; i++) {
_filterBuffer[i * 2] = (int16_t)(_leftChannelFactor * (double)monoBuffer[i]);
_filterBuffer[i * 2 + 1] = (int16_t)(_rightChannelFactor * (double)monoBuffer[i]);
}
return _filterBuffer;
}

View file

@ -0,0 +1,16 @@
#pragma once
#include "stdafx.h"
#include "BaseSoundFilter.h"
class StereoPanningFilter : public BaseSoundFilter
{
private:
const double _baseFactor = 0.70710678118654752440084436210485; // == sqrt(2)/2
double _leftChannelFactor = 0;
double _rightChannelFactor = 0;
void UpdateFactors();
public:
int16_t* ApplyFilter(int16_t* monoBuffer, size_t sampleCount);
};

View file

@ -30,6 +30,12 @@ namespace Mesen.GUI.Config
public bool ReduceSoundInBackground = true;
public bool MuteSoundInBackground = false;
public bool SwapDutyCycles = false;
public InteropEmu.StereoFilter StereoFilter;
public Int32 StereoDelay = 15;
public Int32 StereoPanningAngle = 15;
public bool ReverbEnabled = false;
public UInt32 ReverbStrength = 5;
public UInt32 ReverbDelay = 10;
public AudioInfo()
{
@ -67,6 +73,16 @@ namespace Mesen.GUI.Config
InteropEmu.SetFlag(EmulationFlags.ReduceSoundInBackground, audioInfo.ReduceSoundInBackground);
InteropEmu.SetFlag(EmulationFlags.SwapDutyCycles, audioInfo.SwapDutyCycles);
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);
}
}
}
}

View file

@ -83,6 +83,17 @@
<Control ID="tpgGeneral">Général</Control>
<Control ID="tpgAdvanced">Avancé</Control>
<Control ID="chkSwapDutyCycles">Inverser le rapport cyclique des canaux Square 1 et Square 2</Control>
<Control ID="tpgEffects">Effets</Control>
<Control ID="grpStereo">Stéréo</Control>
<Control ID="radStereoDisabled">Désactivé</Control>
<Control ID="radStereoDelay">Délai</Control>
<Control ID="radStereoPanning">Panoramique</Control>
<Control ID="lblStereoDelayMs">ms</Control>
<Control ID="lblStereoPanningAngle">(angle en degrés)</Control>
<Control ID="grpReverb">Réverbération</Control>
<Control ID="chkReverbEnabled">Activer la réverbération</Control>
<Control ID="lblReverbDelay">Délai :</Control>
<Control ID="lblReverbStrength">Force :</Control>
<Control ID="chkMuteSoundInBackground">Fermer le son lorsque Mesen est en arrière-plan</Control>
<Control ID="chkReduceSoundInBackground">Réduire le volume lorsque Mesen est en arrière-plan</Control>
<Control ID="chkEnableAudio">Activer le son</Control>

View file

@ -83,6 +83,17 @@
<Control ID="tpgGeneral">全般</Control>
<Control ID="tpgAdvanced">詳細設定</Control>
<Control ID="chkSwapDutyCycles">Squareチャンネルのデューティサイクルをスワップする</Control>
<Control ID="tpgEffects">エフェクト</Control>
<Control ID="grpStereo">ステレオ</Control>
<Control ID="radStereoDisabled">無効</Control>
<Control ID="radStereoDelay">ディレイ</Control>
<Control ID="radStereoPanning">パニング</Control>
<Control ID="lblStereoDelayMs">ミリ秒</Control>
<Control ID="lblStereoPanningAngle">(角度)</Control>
<Control ID="grpReverb">残響</Control>
<Control ID="chkReverbEnabled">残響を有効にする</Control>
<Control ID="lblReverbDelay">ディレイ:</Control>
<Control ID="lblReverbStrength">強度:</Control>
<Control ID="chkMuteSoundInBackground">Mesenが最前面ではない時、音声をミュートにする</Control>
<Control ID="chkReduceSoundInBackground">Mesenが最前面ではない時、音声を低くする</Control>
<Control ID="chkEnableAudio">音声オン</Control>

View file

@ -181,7 +181,9 @@ namespace Mesen.GUI.Forms
NumericUpDown nud = kvp.Value as NumericUpDown;
decimal val;
if(field.FieldType == typeof(UInt32)) {
val = (uint)value;
val = (UInt32)value;
} else if(field.FieldType == typeof(Int32)) {
val = (Int32)value;
} else {
val = (decimal)(double)value;
}
@ -251,6 +253,8 @@ namespace Mesen.GUI.Forms
} else if(kvp.Value is NumericUpDown) {
if(field.FieldType == typeof(UInt32)) {
field.SetValue(Entity, (UInt32)((NumericUpDown)kvp.Value).Value);
} else if(field.FieldType == typeof(Int32)) {
field.SetValue(Entity, (Int32)((NumericUpDown)kvp.Value).Value);
} else {
field.SetValue(Entity, (double)((NumericUpDown)kvp.Value).Value);
}

View file

@ -57,6 +57,26 @@
this.tabMain = new System.Windows.Forms.TabControl();
this.tpgGeneral = new System.Windows.Forms.TabPage();
this.tpgVolume = new System.Windows.Forms.TabPage();
this.tpgEffects = new System.Windows.Forms.TabPage();
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
this.grpStereo = new System.Windows.Forms.GroupBox();
this.tlpStereoFilter = new System.Windows.Forms.TableLayoutPanel();
this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel();
this.nudStereoDelay = new System.Windows.Forms.NumericUpDown();
this.lblStereoDelayMs = new System.Windows.Forms.Label();
this.radStereoDisabled = new System.Windows.Forms.RadioButton();
this.radStereoDelay = new System.Windows.Forms.RadioButton();
this.radStereoPanning = new System.Windows.Forms.RadioButton();
this.flowLayoutPanel4 = new System.Windows.Forms.FlowLayoutPanel();
this.nudStereoPanning = new System.Windows.Forms.NumericUpDown();
this.lblStereoPanningAngle = 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();
this.lblReverbStrength = new System.Windows.Forms.Label();
this.lblReverbDelay = new System.Windows.Forms.Label();
this.trkReverbDelay = new System.Windows.Forms.TrackBar();
this.trkReverbStrength = new System.Windows.Forms.TrackBar();
this.tpgAdvanced = new System.Windows.Forms.TabPage();
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.chkSwapDutyCycles = new System.Windows.Forms.CheckBox();
@ -69,6 +89,18 @@
this.tabMain.SuspendLayout();
this.tpgGeneral.SuspendLayout();
this.tpgVolume.SuspendLayout();
this.tpgEffects.SuspendLayout();
this.tableLayoutPanel4.SuspendLayout();
this.grpStereo.SuspendLayout();
this.tlpStereoFilter.SuspendLayout();
this.flowLayoutPanel3.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.nudStereoDelay)).BeginInit();
this.flowLayoutPanel4.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.nudStereoPanning)).BeginInit();
this.grpReverb.SuspendLayout();
this.tableLayoutPanel5.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.trkReverbDelay)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.trkReverbStrength)).BeginInit();
this.tpgAdvanced.SuspendLayout();
this.tableLayoutPanel3.SuspendLayout();
this.SuspendLayout();
@ -124,7 +156,6 @@
// trkDmcVol
//
this.trkDmcVol.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.trkDmcVol.Text = "DMC";
this.trkDmcVol.Location = new System.Drawing.Point(384, 0);
this.trkDmcVol.Margin = new System.Windows.Forms.Padding(0);
this.trkDmcVol.Maximum = 100;
@ -133,12 +164,12 @@
this.trkDmcVol.Name = "trkDmcVol";
this.trkDmcVol.Size = new System.Drawing.Size(63, 160);
this.trkDmcVol.TabIndex = 16;
this.trkDmcVol.Text = "DMC";
this.trkDmcVol.Value = 50;
//
// trkNoiseVol
//
this.trkNoiseVol.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.trkNoiseVol.Text = "Noise";
this.trkNoiseVol.Location = new System.Drawing.Point(306, 0);
this.trkNoiseVol.Margin = new System.Windows.Forms.Padding(0);
this.trkNoiseVol.Maximum = 100;
@ -147,12 +178,12 @@
this.trkNoiseVol.Name = "trkNoiseVol";
this.trkNoiseVol.Size = new System.Drawing.Size(63, 160);
this.trkNoiseVol.TabIndex = 15;
this.trkNoiseVol.Text = "Noise";
this.trkNoiseVol.Value = 50;
//
// trkTriangleVol
//
this.trkTriangleVol.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.trkTriangleVol.Text = "Triangle";
this.trkTriangleVol.Location = new System.Drawing.Point(231, 0);
this.trkTriangleVol.Margin = new System.Windows.Forms.Padding(0);
this.trkTriangleVol.Maximum = 100;
@ -161,12 +192,12 @@
this.trkTriangleVol.Name = "trkTriangleVol";
this.trkTriangleVol.Size = new System.Drawing.Size(63, 160);
this.trkTriangleVol.TabIndex = 14;
this.trkTriangleVol.Text = "Triangle";
this.trkTriangleVol.Value = 50;
//
// trkSquare2Vol
//
this.trkSquare2Vol.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.trkSquare2Vol.Text = "Square 2";
this.trkSquare2Vol.Location = new System.Drawing.Point(156, 0);
this.trkSquare2Vol.Margin = new System.Windows.Forms.Padding(0);
this.trkSquare2Vol.Maximum = 100;
@ -175,12 +206,12 @@
this.trkSquare2Vol.Name = "trkSquare2Vol";
this.trkSquare2Vol.Size = new System.Drawing.Size(63, 160);
this.trkSquare2Vol.TabIndex = 13;
this.trkSquare2Vol.Text = "Square 2";
this.trkSquare2Vol.Value = 50;
//
// trkSquare1Vol
//
this.trkSquare1Vol.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.trkSquare1Vol.Text = "Square 1";
this.trkSquare1Vol.Location = new System.Drawing.Point(81, 0);
this.trkSquare1Vol.Margin = new System.Windows.Forms.Padding(0);
this.trkSquare1Vol.Maximum = 100;
@ -189,12 +220,12 @@
this.trkSquare1Vol.Name = "trkSquare1Vol";
this.trkSquare1Vol.Size = new System.Drawing.Size(63, 160);
this.trkSquare1Vol.TabIndex = 12;
this.trkSquare1Vol.Text = "Square 1";
this.trkSquare1Vol.Value = 50;
//
// trkMaster
//
this.trkMaster.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.trkMaster.Text = "Master";
this.trkMaster.Location = new System.Drawing.Point(6, 0);
this.trkMaster.Margin = new System.Windows.Forms.Padding(0);
this.trkMaster.Maximum = 100;
@ -203,12 +234,12 @@
this.trkMaster.Name = "trkMaster";
this.trkMaster.Size = new System.Drawing.Size(63, 160);
this.trkMaster.TabIndex = 11;
this.trkMaster.Text = "Master";
this.trkMaster.Value = 50;
//
// trkFdsVol
//
this.trkFdsVol.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.trkFdsVol.Text = "FDS";
this.trkFdsVol.Location = new System.Drawing.Point(6, 160);
this.trkFdsVol.Margin = new System.Windows.Forms.Padding(0);
this.trkFdsVol.Maximum = 100;
@ -217,12 +248,12 @@
this.trkFdsVol.Name = "trkFdsVol";
this.trkFdsVol.Size = new System.Drawing.Size(63, 160);
this.trkFdsVol.TabIndex = 17;
this.trkFdsVol.Text = "FDS";
this.trkFdsVol.Value = 50;
//
// trkMmc5Vol
//
this.trkMmc5Vol.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.trkMmc5Vol.Text = "MMC5";
this.trkMmc5Vol.Enabled = false;
this.trkMmc5Vol.Location = new System.Drawing.Point(81, 160);
this.trkMmc5Vol.Margin = new System.Windows.Forms.Padding(0);
@ -232,12 +263,12 @@
this.trkMmc5Vol.Name = "trkMmc5Vol";
this.trkMmc5Vol.Size = new System.Drawing.Size(63, 160);
this.trkMmc5Vol.TabIndex = 18;
this.trkMmc5Vol.Text = "MMC5";
this.trkMmc5Vol.Value = 50;
//
// trkVrc6Vol
//
this.trkVrc6Vol.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.trkVrc6Vol.Text = "VRC6";
this.trkVrc6Vol.Enabled = false;
this.trkVrc6Vol.Location = new System.Drawing.Point(156, 160);
this.trkVrc6Vol.Margin = new System.Windows.Forms.Padding(0);
@ -247,12 +278,12 @@
this.trkVrc6Vol.Name = "trkVrc6Vol";
this.trkVrc6Vol.Size = new System.Drawing.Size(63, 160);
this.trkVrc6Vol.TabIndex = 19;
this.trkVrc6Vol.Text = "VRC6";
this.trkVrc6Vol.Value = 50;
//
// trkVrc7Vol
//
this.trkVrc7Vol.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.trkVrc7Vol.Text = "VRC7";
this.trkVrc7Vol.Enabled = false;
this.trkVrc7Vol.Location = new System.Drawing.Point(231, 160);
this.trkVrc7Vol.Margin = new System.Windows.Forms.Padding(0);
@ -262,12 +293,12 @@
this.trkVrc7Vol.Name = "trkVrc7Vol";
this.trkVrc7Vol.Size = new System.Drawing.Size(63, 160);
this.trkVrc7Vol.TabIndex = 20;
this.trkVrc7Vol.Text = "VRC7";
this.trkVrc7Vol.Value = 50;
//
// trkNamco163Vol
//
this.trkNamco163Vol.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.trkNamco163Vol.Text = "Namco";
this.trkNamco163Vol.Enabled = false;
this.trkNamco163Vol.Location = new System.Drawing.Point(306, 160);
this.trkNamco163Vol.Margin = new System.Windows.Forms.Padding(0);
@ -277,12 +308,12 @@
this.trkNamco163Vol.Name = "trkNamco163Vol";
this.trkNamco163Vol.Size = new System.Drawing.Size(63, 160);
this.trkNamco163Vol.TabIndex = 21;
this.trkNamco163Vol.Text = "Namco";
this.trkNamco163Vol.Value = 50;
//
// trkSunsoft5b
//
this.trkSunsoft5b.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.trkSunsoft5b.Text = "Sunsoft";
this.trkSunsoft5b.Enabled = false;
this.trkSunsoft5b.Location = new System.Drawing.Point(384, 160);
this.trkSunsoft5b.Margin = new System.Windows.Forms.Padding(0);
@ -292,6 +323,7 @@
this.trkSunsoft5b.Name = "trkSunsoft5b";
this.trkSunsoft5b.Size = new System.Drawing.Size(63, 160);
this.trkSunsoft5b.TabIndex = 22;
this.trkSunsoft5b.Text = "Sunsoft";
this.trkSunsoft5b.Value = 50;
//
// tableLayoutPanel2
@ -468,6 +500,7 @@
//
this.tabMain.Controls.Add(this.tpgGeneral);
this.tabMain.Controls.Add(this.tpgVolume);
this.tabMain.Controls.Add(this.tpgEffects);
this.tabMain.Controls.Add(this.tpgAdvanced);
this.tabMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabMain.Location = new System.Drawing.Point(0, 0);
@ -498,6 +531,252 @@
this.tpgVolume.Text = "Volume";
this.tpgVolume.UseVisualStyleBackColor = true;
//
// tpgEffects
//
this.tpgEffects.Controls.Add(this.tableLayoutPanel4);
this.tpgEffects.Location = new System.Drawing.Point(4, 22);
this.tpgEffects.Name = "tpgEffects";
this.tpgEffects.Padding = new System.Windows.Forms.Padding(3);
this.tpgEffects.Size = new System.Drawing.Size(469, 349);
this.tpgEffects.TabIndex = 3;
this.tpgEffects.Text = "Effects";
this.tpgEffects.UseVisualStyleBackColor = true;
//
// tableLayoutPanel4
//
this.tableLayoutPanel4.ColumnCount = 1;
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel4.Controls.Add(this.grpStereo, 0, 0);
this.tableLayoutPanel4.Controls.Add(this.grpReverb, 0, 1);
this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel4.Location = new System.Drawing.Point(3, 3);
this.tableLayoutPanel4.Name = "tableLayoutPanel4";
this.tableLayoutPanel4.RowCount = 3;
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel4.Size = new System.Drawing.Size(463, 343);
this.tableLayoutPanel4.TabIndex = 0;
//
// grpStereo
//
this.grpStereo.Controls.Add(this.tlpStereoFilter);
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.TabIndex = 0;
this.grpStereo.TabStop = false;
this.grpStereo.Text = "Stereo";
//
// tlpStereoFilter
//
this.tlpStereoFilter.ColumnCount = 2;
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.flowLayoutPanel3, 1, 1);
this.tlpStereoFilter.Controls.Add(this.radStereoDisabled, 0, 0);
this.tlpStereoFilter.Controls.Add(this.radStereoDelay, 0, 1);
this.tlpStereoFilter.Controls.Add(this.radStereoPanning, 0, 2);
this.tlpStereoFilter.Controls.Add(this.flowLayoutPanel4, 1, 2);
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.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.TabIndex = 0;
//
// flowLayoutPanel3
//
this.flowLayoutPanel3.Controls.Add(this.nudStereoDelay);
this.flowLayoutPanel3.Controls.Add(this.lblStereoDelayMs);
this.flowLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
this.flowLayoutPanel3.Location = new System.Drawing.Point(72, 23);
this.flowLayoutPanel3.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel3.Name = "flowLayoutPanel3";
this.flowLayoutPanel3.Size = new System.Drawing.Size(379, 26);
this.flowLayoutPanel3.TabIndex = 1;
//
// nudStereoDelay
//
this.nudStereoDelay.Location = new System.Drawing.Point(3, 3);
this.nudStereoDelay.Name = "nudStereoDelay";
this.nudStereoDelay.Size = new System.Drawing.Size(45, 20);
this.nudStereoDelay.TabIndex = 1;
//
// lblStereoDelayMs
//
this.lblStereoDelayMs.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblStereoDelayMs.AutoSize = true;
this.lblStereoDelayMs.Location = new System.Drawing.Point(54, 6);
this.lblStereoDelayMs.Name = "lblStereoDelayMs";
this.lblStereoDelayMs.Size = new System.Drawing.Size(20, 13);
this.lblStereoDelayMs.TabIndex = 1;
this.lblStereoDelayMs.Text = "ms";
//
// radStereoDisabled
//
this.radStereoDisabled.AutoSize = true;
this.radStereoDisabled.Location = new System.Drawing.Point(3, 3);
this.radStereoDisabled.Name = "radStereoDisabled";
this.radStereoDisabled.Size = new System.Drawing.Size(66, 17);
this.radStereoDisabled.TabIndex = 1;
this.radStereoDisabled.TabStop = true;
this.radStereoDisabled.Tag = "None";
this.radStereoDisabled.Text = "Disabled";
this.radStereoDisabled.UseVisualStyleBackColor = true;
//
// radStereoDelay
//
this.radStereoDelay.AutoSize = true;
this.radStereoDelay.Location = new System.Drawing.Point(3, 26);
this.radStereoDelay.Name = "radStereoDelay";
this.radStereoDelay.Size = new System.Drawing.Size(52, 17);
this.radStereoDelay.TabIndex = 2;
this.radStereoDelay.TabStop = true;
this.radStereoDelay.Tag = "Delay";
this.radStereoDelay.Text = "Delay";
this.radStereoDelay.UseVisualStyleBackColor = true;
//
// radStereoPanning
//
this.radStereoPanning.AutoSize = true;
this.radStereoPanning.Location = new System.Drawing.Point(3, 52);
this.radStereoPanning.Name = "radStereoPanning";
this.radStereoPanning.Size = new System.Drawing.Size(64, 17);
this.radStereoPanning.TabIndex = 3;
this.radStereoPanning.TabStop = true;
this.radStereoPanning.Tag = "Panning";
this.radStereoPanning.Text = "Panning";
this.radStereoPanning.UseVisualStyleBackColor = true;
//
// flowLayoutPanel4
//
this.flowLayoutPanel4.Controls.Add(this.nudStereoPanning);
this.flowLayoutPanel4.Controls.Add(this.lblStereoPanningAngle);
this.flowLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
this.flowLayoutPanel4.Location = new System.Drawing.Point(72, 49);
this.flowLayoutPanel4.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel4.Name = "flowLayoutPanel4";
this.flowLayoutPanel4.Size = new System.Drawing.Size(379, 26);
this.flowLayoutPanel4.TabIndex = 4;
//
// nudStereoPanning
//
this.nudStereoPanning.Location = new System.Drawing.Point(3, 3);
this.nudStereoPanning.Maximum = new decimal(new int[] {
180,
0,
0,
0});
this.nudStereoPanning.Minimum = new decimal(new int[] {
180,
0,
0,
-2147483648});
this.nudStereoPanning.Name = "nudStereoPanning";
this.nudStereoPanning.Size = new System.Drawing.Size(45, 20);
this.nudStereoPanning.TabIndex = 1;
//
// lblStereoPanningAngle
//
this.lblStereoPanningAngle.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblStereoPanningAngle.AutoSize = true;
this.lblStereoPanningAngle.Location = new System.Drawing.Point(54, 6);
this.lblStereoPanningAngle.Name = "lblStereoPanningAngle";
this.lblStereoPanningAngle.Size = new System.Drawing.Size(92, 13);
this.lblStereoPanningAngle.TabIndex = 1;
this.lblStereoPanningAngle.Text = "(Angle in degrees)";
//
// 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.Name = "grpReverb";
this.grpReverb.Size = new System.Drawing.Size(457, 109);
this.grpReverb.TabIndex = 1;
this.grpReverb.TabStop = false;
this.grpReverb.Text = "Reverb";
//
// tableLayoutPanel5
//
this.tableLayoutPanel5.ColumnCount = 2;
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel5.Controls.Add(this.chkReverbEnabled, 0, 0);
this.tableLayoutPanel5.Controls.Add(this.lblReverbStrength, 0, 1);
this.tableLayoutPanel5.Controls.Add(this.lblReverbDelay, 0, 2);
this.tableLayoutPanel5.Controls.Add(this.trkReverbDelay, 1, 2);
this.tableLayoutPanel5.Controls.Add(this.trkReverbStrength, 1, 1);
this.tableLayoutPanel5.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel5.Location = new System.Drawing.Point(3, 16);
this.tableLayoutPanel5.Name = "tableLayoutPanel5";
this.tableLayoutPanel5.RowCount = 4;
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 32F));
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 32F));
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel5.Size = new System.Drawing.Size(451, 90);
this.tableLayoutPanel5.TabIndex = 0;
//
// chkReverbEnabled
//
this.chkReverbEnabled.AutoSize = true;
this.tableLayoutPanel5.SetColumnSpan(this.chkReverbEnabled, 2);
this.chkReverbEnabled.Location = new System.Drawing.Point(3, 3);
this.chkReverbEnabled.Name = "chkReverbEnabled";
this.chkReverbEnabled.Size = new System.Drawing.Size(97, 17);
this.chkReverbEnabled.TabIndex = 0;
this.chkReverbEnabled.Text = "Enable Reverb";
this.chkReverbEnabled.UseVisualStyleBackColor = true;
//
// lblReverbStrength
//
this.lblReverbStrength.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblReverbStrength.AutoSize = true;
this.lblReverbStrength.Location = new System.Drawing.Point(3, 32);
this.lblReverbStrength.Name = "lblReverbStrength";
this.lblReverbStrength.Size = new System.Drawing.Size(50, 13);
this.lblReverbStrength.TabIndex = 2;
this.lblReverbStrength.Text = "Strength:";
//
// lblReverbDelay
//
this.lblReverbDelay.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblReverbDelay.AutoSize = true;
this.lblReverbDelay.Location = new System.Drawing.Point(3, 64);
this.lblReverbDelay.Name = "lblReverbDelay";
this.lblReverbDelay.Size = new System.Drawing.Size(37, 13);
this.lblReverbDelay.TabIndex = 3;
this.lblReverbDelay.Text = "Delay:";
//
// trkReverbDelay
//
this.trkReverbDelay.BackColor = System.Drawing.SystemColors.ControlLightLight;
this.trkReverbDelay.Location = new System.Drawing.Point(59, 58);
this.trkReverbDelay.Maximum = 30;
this.trkReverbDelay.Minimum = 1;
this.trkReverbDelay.Name = "trkReverbDelay";
this.trkReverbDelay.Size = new System.Drawing.Size(104, 26);
this.trkReverbDelay.TabIndex = 4;
this.trkReverbDelay.TickFrequency = 3;
this.trkReverbDelay.Value = 1;
//
// trkReverbStrength
//
this.trkReverbStrength.BackColor = System.Drawing.SystemColors.ControlLightLight;
this.trkReverbStrength.Location = new System.Drawing.Point(59, 26);
this.trkReverbStrength.Minimum = 1;
this.trkReverbStrength.Name = "trkReverbStrength";
this.trkReverbStrength.Size = new System.Drawing.Size(104, 26);
this.trkReverbStrength.TabIndex = 1;
this.trkReverbStrength.Value = 1;
//
// tpgAdvanced
//
this.tpgAdvanced.Controls.Add(this.tableLayoutPanel3);
@ -559,6 +838,22 @@
this.tabMain.ResumeLayout(false);
this.tpgGeneral.ResumeLayout(false);
this.tpgVolume.ResumeLayout(false);
this.tpgEffects.ResumeLayout(false);
this.tableLayoutPanel4.ResumeLayout(false);
this.grpStereo.ResumeLayout(false);
this.tlpStereoFilter.ResumeLayout(false);
this.tlpStereoFilter.PerformLayout();
this.flowLayoutPanel3.ResumeLayout(false);
this.flowLayoutPanel3.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.nudStereoDelay)).EndInit();
this.flowLayoutPanel4.ResumeLayout(false);
this.flowLayoutPanel4.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.nudStereoPanning)).EndInit();
this.grpReverb.ResumeLayout(false);
this.tableLayoutPanel5.ResumeLayout(false);
this.tableLayoutPanel5.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.trkReverbDelay)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.trkReverbStrength)).EndInit();
this.tpgAdvanced.ResumeLayout(false);
this.tableLayoutPanel3.ResumeLayout(false);
this.tableLayoutPanel3.PerformLayout();
@ -601,5 +896,25 @@
private System.Windows.Forms.TabPage tpgAdvanced;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
private System.Windows.Forms.CheckBox chkSwapDutyCycles;
private System.Windows.Forms.TabPage tpgEffects;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
private System.Windows.Forms.GroupBox grpStereo;
private System.Windows.Forms.TableLayoutPanel tlpStereoFilter;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel3;
private System.Windows.Forms.NumericUpDown nudStereoDelay;
private System.Windows.Forms.Label lblStereoDelayMs;
private System.Windows.Forms.RadioButton radStereoDisabled;
private System.Windows.Forms.RadioButton radStereoDelay;
private System.Windows.Forms.RadioButton radStereoPanning;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel4;
private System.Windows.Forms.NumericUpDown nudStereoPanning;
private System.Windows.Forms.Label lblStereoPanningAngle;
private System.Windows.Forms.GroupBox grpReverb;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel5;
private System.Windows.Forms.CheckBox chkReverbEnabled;
private System.Windows.Forms.Label lblReverbStrength;
private System.Windows.Forms.Label lblReverbDelay;
private System.Windows.Forms.TrackBar trkReverbDelay;
private System.Windows.Forms.TrackBar trkReverbStrength;
}
}

View file

@ -44,6 +44,18 @@ namespace Mesen.GUI.Forms.Config
AddBinding("MuteSoundInBackground", chkMuteSoundInBackground);
AddBinding("SwapDutyCycles", chkSwapDutyCycles);
radStereoDisabled.Tag = InteropEmu.StereoFilter.None;
radStereoDelay.Tag = InteropEmu.StereoFilter.Delay;
radStereoPanning.Tag = InteropEmu.StereoFilter.Panning;
AddBinding("StereoFilter", tlpStereoFilter);
AddBinding("StereoDelay", nudStereoDelay);
AddBinding("StereoPanningAngle", nudStereoPanning);
AddBinding("ReverbEnabled", chkReverbEnabled);
AddBinding("ReverbDelay", trkReverbDelay);
AddBinding("ReverbStrength", trkReverbStrength);
}
protected override void OnFormClosed(FormClosedEventArgs e)

View file

@ -102,6 +102,10 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void SetChannelVolume(AudioChannel channel, double volume);
[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 SetNesModel(NesModel model);
[DllImport(DLLPath)] public static extern void SetEmulationSpeed(UInt32 emulationSpeed);
[DllImport(DLLPath)] public static extern void SetOverscanDimensions(UInt32 left, UInt32 right, UInt32 top, UInt32 bottom);
@ -361,6 +365,13 @@ namespace Mesen.GUI
public UInt32 TurboSelect;
}
public enum StereoFilter
{
None = 0,
Delay = 1,
Panning = 2,
}
public struct ScreenSize
{
public Int32 Width;

View file

@ -254,6 +254,11 @@ namespace InteropEmu {
DllExport void __stdcall SetMasterVolume(double volume) { EmulationSettings::SetMasterVolume(volume); }
DllExport void __stdcall SetSampleRate(uint32_t sampleRate) { EmulationSettings::SetSampleRate(sampleRate); }
DllExport void __stdcall SetAudioLatency(uint32_t msLatency) { EmulationSettings::SetAudioLatency(msLatency); }
DllExport void __stdcall SetStereoFilter(StereoFilter stereoFilter) { EmulationSettings::SetStereoFilter(stereoFilter); }
DllExport void __stdcall SetStereoDelay(int32_t delay) { EmulationSettings::SetStereoDelay(delay); }
DllExport void __stdcall SetStereoPanningAngle(double angle) { EmulationSettings::SetStereoPanningAngle(angle); }
DllExport void __stdcall SetReverbParameters(double strength, double delay) { EmulationSettings::SetReverbParameters(strength, delay); }
DllExport void __stdcall SetNesModel(uint32_t model) { EmulationSettings::SetNesModel((NesModel)model); }
DllExport void __stdcall SetOverscanDimensions(uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) { EmulationSettings::SetOverscanDimensions(left, right, top, bottom); }
DllExport void __stdcall SetEmulationSpeed(uint32_t emulationSpeed) { EmulationSettings::SetEmulationSpeed(emulationSpeed); }

View file

@ -12,7 +12,7 @@ SoundManager::SoundManager(HWND hwnd)
memset(&_audioDeviceID, 0, sizeof(_audioDeviceID));
if(InitializeDirectSound(44100)) {
if(InitializeDirectSound(44100, false)) {
SoundMixer::RegisterAudioDevice(this);
} else {
MessageManager::DisplayMessage("Error", "Could not initialize audio system");
@ -69,7 +69,7 @@ void SoundManager::SetAudioDevice(string deviceName)
}
}
bool SoundManager::InitializeDirectSound(uint32_t sampleRate)
bool SoundManager::InitializeDirectSound(uint32_t sampleRate, bool isStereo)
{
HRESULT result;
DSBUFFERDESC bufferDesc;
@ -103,11 +103,12 @@ bool SoundManager::InitializeDirectSound(uint32_t sampleRate)
// Setup the format of the primary sound bufffer.
_sampleRate = sampleRate;
_isStereo = isStereo;
waveFormat.wFormatTag = WAVE_FORMAT_PCM;
waveFormat.nSamplesPerSec = _sampleRate;
waveFormat.wBitsPerSample = 16;
waveFormat.nChannels = 1;
waveFormat.nChannels = isStereo ? 2 : 1;
waveFormat.nBlockAlign = (waveFormat.wBitsPerSample / 8) * waveFormat.nChannels;
waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
waveFormat.cbSize = 0;
@ -225,14 +226,21 @@ void SoundManager::Play()
}
}
void SoundManager::PlayBuffer(int16_t *soundBuffer, uint32_t soundBufferSize, uint32_t sampleRate)
void SoundManager::PlayBuffer(int16_t *soundBuffer, uint32_t sampleCount, uint32_t sampleRate, bool isStereo)
{
if(_sampleRate != sampleRate || _needReset) {
uint32_t bytesPerSample = (SoundMixer::BitsPerSample / 8);
if(_sampleRate != sampleRate || _isStereo != isStereo || _needReset) {
Release();
InitializeDirectSound(sampleRate);
InitializeDirectSound(sampleRate, isStereo);
}
int32_t byteLatency = (int32_t)((float)(sampleRate * EmulationSettings::GetAudioLatency()) / 1000.0f * (SoundMixer::BitsPerSample / 8));
if(isStereo) {
bytesPerSample *= 2;
}
uint32_t soundBufferSize = sampleCount * bytesPerSample;
int32_t byteLatency = (int32_t)((float)(sampleRate * EmulationSettings::GetAudioLatency()) / 1000.0f * bytesPerSample);
if(byteLatency != _previousLatency) {
Stop();
_previousLatency = byteLatency;

View file

@ -16,7 +16,7 @@ public:
~SoundManager();
void Release();
void PlayBuffer(int16_t *soundBuffer, uint32_t bufferSize, uint32_t sampleRate);
void PlayBuffer(int16_t *soundBuffer, uint32_t bufferSize, uint32_t sampleRate, bool isStereo);
void Play();
void Pause();
void Stop();
@ -27,7 +27,7 @@ public:
private:
vector<SoundDeviceInfo> GetAvailableDeviceInfo();
static bool CALLBACK DirectSoundEnumProc(LPGUID lpGUID, LPCWSTR lpszDesc, LPCSTR lpszDrvName, LPVOID lpContext);
bool InitializeDirectSound(uint32_t sampleRate);
bool InitializeDirectSound(uint32_t sampleRate, bool isStereo);
void ShutdownDirectSound();
void ClearSecondaryBuffer();
void CopyToSecondaryBuffer(uint8_t *data, uint32_t size);
@ -40,6 +40,7 @@ private:
uint16_t _lastWriteOffset = 0;
uint16_t _previousLatency = 0;
uint32_t _sampleRate = 0;
bool _isStereo = false;
IDirectSound8* _directSound;
IDirectSoundBuffer* _primaryBuffer;