UI: Added audio options (sample rate, volume, latency, equalizer)

This commit is contained in:
Sour 2019-03-10 17:39:14 -04:00
parent 60af2e2f64
commit 2893664d0f
33 changed files with 1866 additions and 56 deletions

View file

@ -21,6 +21,7 @@
#include "KeyManager.h"
#include "EventType.h"
#include "EmuSettings.h"
#include "DebugStats.h"
#include "../Utilities/Timer.h"
#include "../Utilities/VirtualFile.h"
#include "../Utilities/PlatformUtilities.h"
@ -36,7 +37,7 @@ void Console::Initialize()
_notificationManager.reset(new NotificationManager());
_videoDecoder.reset(new VideoDecoder(shared_from_this()));
_videoRenderer.reset(new VideoRenderer(shared_from_this()));
_soundMixer.reset(new SoundMixer());
_soundMixer.reset(new SoundMixer(this));
_debugHud.reset(new DebugHud());
_videoDecoder->StartThread();
@ -62,6 +63,8 @@ void Console::Run()
return;
}
DebugStats stats(this);
Timer lastFrameTimer;
_stopFlag = false;
uint32_t previousFrameCount = 0;
@ -69,7 +72,8 @@ void Console::Run()
PlatformUtilities::EnableHighResolutionTimer();
uint32_t keyCode = KeyManager::GetKeyCode("Tab");
uint32_t tabKeyCode = KeyManager::GetKeyCode("Tab");
uint32_t semiKeyCode = KeyManager::GetKeyCode(";");
_videoDecoder->StartThread();
_emulationThreadId = std::this_thread::get_id();
@ -79,10 +83,17 @@ void Console::Run()
_cpu->Exec();
if(previousFrameCount != _ppu->GetFrameCount()) {
if(!KeyManager::IsKeyPressed(keyCode)) {
if(!KeyManager::IsKeyPressed(tabKeyCode)) {
frameLimiter.ProcessFrame();
frameLimiter.WaitForNextFrame();
}
if(KeyManager::IsKeyPressed(semiKeyCode)) {
double lastFrameTime = lastFrameTimer.GetElapsedMS();
lastFrameTimer.Reset();
stats.DisplayStats(lastFrameTime);
}
previousFrameCount = _ppu->GetFrameCount();
}
}

View file

@ -60,6 +60,7 @@
<ClInclude Include="ControlManager.h" />
<ClInclude Include="Cpu.h" />
<ClInclude Include="DebugBreakHelper.h" />
<ClInclude Include="DebugStats.h" />
<ClInclude Include="DummyCpu.h" />
<ClInclude Include="EmuSettings.h" />
<ClInclude Include="EventManager.h" />
@ -108,6 +109,7 @@
<ClInclude Include="SnesController.h" />
<ClInclude Include="SNES_SPC.h" />
<ClInclude Include="SoundMixer.h" />
<ClInclude Include="SoundResampler.h" />
<ClInclude Include="Spc.h" />
<ClInclude Include="SPC_CPU.h" />
<ClInclude Include="SPC_DSP.h" />
@ -132,6 +134,7 @@
<ClCompile Include="Cpu.Instructions.cpp" />
<ClCompile Include="Debugger.cpp" />
<ClCompile Include="DebugHud.cpp" />
<ClCompile Include="DebugStats.cpp" />
<ClCompile Include="DefaultVideoFilter.cpp" />
<ClCompile Include="Disassembler.cpp" />
<ClCompile Include="DisassemblyInfo.cpp" />
@ -153,6 +156,7 @@
<ClCompile Include="SNES_SPC_misc.cpp" />
<ClCompile Include="SNES_SPC_state.cpp" />
<ClCompile Include="SoundMixer.cpp" />
<ClCompile Include="SoundResampler.cpp" />
<ClCompile Include="Spc.cpp" />
<ClCompile Include="SPC_DSP.cpp" />
<ClCompile Include="SPC_Filter.cpp" />

View file

@ -44,9 +44,6 @@
<ClInclude Include="IRenderingDevice.h">
<Filter>Interfaces</Filter>
</ClInclude>
<ClInclude Include="BaseSoundManager.h">
<Filter>Misc</Filter>
</ClInclude>
<ClInclude Include="MessageManager.h">
<Filter>Misc</Filter>
</ClInclude>
@ -146,9 +143,6 @@
<ClInclude Include="Spc.h">
<Filter>SNES</Filter>
</ClInclude>
<ClInclude Include="SoundMixer.h">
<Filter>Misc</Filter>
</ClInclude>
<ClInclude Include="RomHandler.h">
<Filter>SNES</Filter>
</ClInclude>
@ -218,6 +212,18 @@
<ClInclude Include="NtscFilter.h">
<Filter>Video</Filter>
</ClInclude>
<ClInclude Include="SoundMixer.h">
<Filter>Audio</Filter>
</ClInclude>
<ClInclude Include="SoundResampler.h">
<Filter>Audio</Filter>
</ClInclude>
<ClInclude Include="BaseSoundManager.h">
<Filter>Audio</Filter>
</ClInclude>
<ClInclude Include="DebugStats.h">
<Filter>Misc</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp" />
@ -236,9 +242,6 @@
<ClCompile Include="Console.cpp">
<Filter>SNES</Filter>
</ClCompile>
<ClCompile Include="BaseSoundManager.cpp">
<Filter>Misc</Filter>
</ClCompile>
<ClCompile Include="MessageManager.cpp">
<Filter>Misc</Filter>
</ClCompile>
@ -296,9 +299,6 @@
<ClCompile Include="Spc.cpp">
<Filter>SNES</Filter>
</ClCompile>
<ClCompile Include="SoundMixer.cpp">
<Filter>Misc</Filter>
</ClCompile>
<ClCompile Include="BaseCartridge.cpp">
<Filter>SNES</Filter>
</ClCompile>
@ -344,6 +344,16 @@
<ClCompile Include="NtscFilter.cpp">
<Filter>Video</Filter>
</ClCompile>
<ClCompile Include="SoundMixer.cpp">
<Filter>Audio</Filter>
</ClCompile>
<ClCompile Include="SoundResampler.cpp">
<Filter>Audio</Filter>
</ClCompile>
<ClCompile Include="BaseSoundManager.cpp">
<Filter>Audio</Filter>
</ClCompile>
<ClCompile Include="DebugStats.cpp" />
</ItemGroup>
<ItemGroup>
<Filter Include="SNES">
@ -370,5 +380,8 @@
<Filter Include="SNES\Input">
<UniqueIdentifier>{3a9ea5fe-e818-4e65-bd50-cb9591de3e0d}</UniqueIdentifier>
</Filter>
<Filter Include="Audio">
<UniqueIdentifier>{cfc63477-84ed-48e4-81dc-8f960303b40a}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

75
Core/DebugStats.cpp Normal file
View file

@ -0,0 +1,75 @@
#include "stdafx.h"
#include "DebugStats.h"
#include "Console.h"
#include "SoundMixer.h"
#include "Ppu.h"
#include "EmuSettings.h"
#include "DebugHud.h"
#include "IAudioDevice.h"
DebugStats::DebugStats(Console * console)
{
_console = console;
}
void DebugStats::DisplayStats(double lastFrameTime)
{
AudioStatistics stats = _console->GetSoundMixer()->GetStatistics();
AudioConfig audioCfg = _console->GetSettings()->GetAudioConfig();
shared_ptr<DebugHud> hud = _console->GetDebugHud();
_frameDurations[_frameDurationIndex] = lastFrameTime;
_frameDurationIndex = (_frameDurationIndex + 1) % 60;
int startFrame = _console->GetPpu()->GetFrameCount();
hud->DrawRectangle(8, 8, 115, 49, 0x40000000, true, 1, startFrame);
hud->DrawRectangle(8, 8, 115, 49, 0xFFFFFF, false, 1, startFrame);
hud->DrawString(10, 10, "Audio Stats", 0xFFFFFF, 0xFF000000, 1, startFrame);
hud->DrawString(10, 21, "Latency: ", 0xFFFFFF, 0xFF000000, 1, startFrame);
int color = (stats.AverageLatency > 0 && std::abs(stats.AverageLatency - audioCfg.AudioLatency) > 3) ? 0xFF0000 : 0xFFFFFF;
std::stringstream ss;
ss << std::fixed << std::setprecision(2) << stats.AverageLatency << " ms";
hud->DrawString(54, 21, ss.str(), color, 0xFF000000, 1, startFrame);
hud->DrawString(10, 30, "Underruns: " + std::to_string(stats.BufferUnderrunEventCount), 0xFFFFFF, 0xFF000000, 1, startFrame);
hud->DrawString(10, 39, "Buffer Size: " + std::to_string(stats.BufferSize / 1024) + "kb", 0xFFFFFF, 0xFF000000, 1, startFrame);
hud->DrawString(10, 48, "Rate: " + std::to_string((uint32_t)(audioCfg.SampleRate * _console->GetSoundMixer()->GetRateAdjustment())) + "Hz", 0xFFFFFF, 0xFF000000, 1, startFrame);
hud->DrawRectangle(132, 8, 115, 49, 0x40000000, true, 1, startFrame);
hud->DrawRectangle(132, 8, 115, 49, 0xFFFFFF, false, 1, startFrame);
hud->DrawString(134, 10, "Video Stats", 0xFFFFFF, 0xFF000000, 1, startFrame);
double totalDuration = 0;
if(_frameDurations) {
for(int i = 0; i < 60; i++) {
totalDuration += _frameDurations[i];
}
}
ss = std::stringstream();
ss << "FPS: " << std::fixed << std::setprecision(4) << (1000 / (totalDuration / 60));
hud->DrawString(134, 21, ss.str(), 0xFFFFFF, 0xFF000000, 1, startFrame);
ss = std::stringstream();
ss << "Last Frame: " << std::fixed << std::setprecision(2) << lastFrameTime << " ms";
hud->DrawString(134, 30, ss.str(), 0xFFFFFF, 0xFF000000, 1, startFrame);
if(_console->GetPpu()->GetFrameCount() > 60) {
_lastFrameMin = std::min(lastFrameTime, _lastFrameMin);
_lastFrameMax = std::max(lastFrameTime, _lastFrameMax);
} else {
_lastFrameMin = 9999;
_lastFrameMax = 0;
}
ss = std::stringstream();
ss << "Min Delay: " << std::fixed << std::setprecision(2) << ((_lastFrameMin < 9999) ? _lastFrameMin : 0.0) << " ms";
hud->DrawString(134, 39, ss.str(), 0xFFFFFF, 0xFF000000, 1, startFrame);
ss = std::stringstream();
ss << "Max Delay: " << std::fixed << std::setprecision(2) << _lastFrameMax << " ms";
hud->DrawString(134, 48, ss.str(), 0xFFFFFF, 0xFF000000, 1, startFrame);
}

19
Core/DebugStats.h Normal file
View file

@ -0,0 +1,19 @@
#pragma once
#include "stdafx.h"
class Console;
class DebugStats
{
private:
Console *_console;
double _frameDurations[60] = {};
uint32_t _frameDurationIndex = 0;
double _lastFrameMin = 9999;
double _lastFrameMax = 0;
public:
DebugStats(Console *console);
void DisplayStats(double lastFrameTime);
};

View file

@ -76,7 +76,7 @@ public:
_argbBuffer = argbBuffer;
_overscan = overscan;
_lineWidth = lineWidth;
_yScale = 1; //TODO
_yScale = 2; //TODO
_xScale = 2; //TODO
InternalDraw();

View file

@ -11,6 +11,25 @@ VideoConfig EmuSettings::GetVideoConfig()
return _video;
}
void EmuSettings::SetAudioConfig(AudioConfig config)
{
//Make a copy of the string and keep it (the original pointer will not be valid after the call is over)
_audioDevice = config.AudioDevice;
config.AudioDevice = _audioDevice.c_str();
_audio = config;
}
AudioConfig EmuSettings::GetAudioConfig()
{
return _audio;
}
uint32_t EmuSettings::GetEmulationSpeed()
{
return 100;
}
double EmuSettings::GetAspectRatio()
{
switch(_video.AspectRatio) {

View file

@ -6,9 +6,16 @@ class EmuSettings
{
private:
VideoConfig _video;
AudioConfig _audio;
string _audioDevice;
public:
void SetVideoConfig(VideoConfig config);
VideoConfig GetVideoConfig();
void SetAudioConfig(AudioConfig config);
AudioConfig GetAudioConfig();
uint32_t GetEmulationSpeed();
double GetAspectRatio();
};

View file

@ -11,15 +11,15 @@ struct AudioStatistics
class IAudioDevice
{
public:
virtual ~IAudioDevice() {}
virtual void PlayBuffer(int16_t *soundBuffer, uint32_t bufferSize, uint32_t sampleRate, bool isStereo) = 0;
virtual void Stop() = 0;
virtual void Pause() = 0;
virtual void ProcessEndOfFrame() = 0;
virtual string GetAvailableDevices() = 0;
virtual void SetAudioDevice(string deviceName) = 0;
virtual AudioStatistics GetStatistics() = 0;
public:
virtual ~IAudioDevice() {}
virtual void PlayBuffer(int16_t *soundBuffer, uint32_t bufferSize, uint32_t sampleRate, bool isStereo) = 0;
virtual void Stop() = 0;
virtual void Pause() = 0;
virtual void ProcessEndOfFrame() = 0;
virtual string GetAvailableDevices() = 0;
virtual void SetAudioDevice(string deviceName) = 0;
virtual AudioStatistics GetStatistics() = 0;
};

View file

@ -84,6 +84,44 @@ struct VideoConfig
int32_t ExclusiveFullscreenRefreshRate = 60;
};
struct AudioConfig
{
const char* AudioDevice = nullptr;
bool EnableAudio = true;
bool DisableDynamicSampleRate = false;
uint32_t MasterVolume = 25;
uint32_t SampleRate = 48000;
uint32_t AudioLatency = 60;
bool MuteSoundInBackground = false;
bool ReduceSoundInBackground = true;
bool ReduceSoundInFastForward = false;
uint32_t VolumeReduction = 75;
bool EnableEqualizer = false;
double Band1Gain = 0;
double Band2Gain = 0;
double Band3Gain = 0;
double Band4Gain = 0;
double Band5Gain = 0;
double Band6Gain = 0;
double Band7Gain = 0;
double Band8Gain = 0;
double Band9Gain = 0;
double Band10Gain = 0;
double Band11Gain = 0;
double Band12Gain = 0;
double Band13Gain = 0;
double Band14Gain = 0;
double Band15Gain = 0;
double Band16Gain = 0;
double Band17Gain = 0;
double Band18Gain = 0;
double Band19Gain = 0;
double Band20Gain = 0;
};
struct OverscanDimensions
{
uint32_t Left = 0;

View file

@ -1,14 +1,22 @@
#include "stdafx.h"
#include "SoundMixer.h"
#include "Console.h"
#include "EmuSettings.h"
#include "SoundResampler.h"
#include "../Utilities/Equalizer.h"
#include "../Utilities/blip_buf.h"
SoundMixer::SoundMixer()
SoundMixer::SoundMixer(Console *console)
{
_console = console;
_audioDevice = nullptr;
_sampleRate = 32000;
_resampler.reset(new SoundResampler(console));
_sampleBuffer = new int16_t[0x10000];
}
SoundMixer::~SoundMixer()
{
delete[] _sampleBuffer;
}
void SoundMixer::RegisterAudioDevice(IAudioDevice *audioDevice)
@ -16,6 +24,15 @@ void SoundMixer::RegisterAudioDevice(IAudioDevice *audioDevice)
_audioDevice = audioDevice;
}
AudioStatistics SoundMixer::GetStatistics()
{
if(_audioDevice) {
return _audioDevice->GetStatistics();
} else {
return AudioStatistics();
}
}
void SoundMixer::StopAudio(bool clearBuffer)
{
if(_audioDevice) {
@ -30,7 +47,51 @@ void SoundMixer::StopAudio(bool clearBuffer)
void SoundMixer::PlayAudioBuffer(int16_t* samples, uint32_t sampleCount)
{
if(_audioDevice) {
_audioDevice->PlayBuffer(samples, sampleCount, _sampleRate, true);
AudioConfig cfg = _console->GetSettings()->GetAudioConfig();
if(!cfg.EnableAudio) {
_audioDevice->Stop();
return;
}
if(cfg.EnableEqualizer) {
ProcessEqualizer(samples, sampleCount);
}
if(cfg.MasterVolume != 25) {
//Apply volume if not using the default value
for(uint32_t i = 0; i < sampleCount * 2; i++) {
samples[i] = (int32_t)samples[i] * (int32_t)cfg.MasterVolume / 25;
}
}
if(cfg.SampleRate == SoundResampler::SpcSampleRate && cfg.DisableDynamicSampleRate) {
_audioDevice->PlayBuffer(samples, sampleCount, cfg.SampleRate, true);
} else {
uint32_t resampledCount = _resampler->Resample(samples, sampleCount, cfg.SampleRate, _sampleBuffer);
_audioDevice->PlayBuffer(_sampleBuffer, resampledCount, cfg.SampleRate, true);
}
_audioDevice->ProcessEndOfFrame();
}
}
void SoundMixer::ProcessEqualizer(int16_t* samples, uint32_t sampleCount)
{
AudioConfig cfg = _console->GetSettings()->GetAudioConfig();
if(!_equalizer) {
_equalizer.reset(new Equalizer());
}
vector<double> bandGains = {
cfg.Band1Gain, cfg.Band2Gain, cfg.Band3Gain, cfg.Band4Gain, cfg.Band5Gain,
cfg.Band6Gain, cfg.Band7Gain, cfg.Band8Gain, cfg.Band9Gain, cfg.Band10Gain,
cfg.Band11Gain, cfg.Band12Gain, cfg.Band13Gain, cfg.Band14Gain, cfg.Band15Gain,
cfg.Band16Gain, cfg.Band17Gain, cfg.Band18Gain, cfg.Band19Gain, cfg.Band20Gain
};
_equalizer->UpdateEqualizers(bandGains, SoundResampler::SpcSampleRate);
_equalizer->ApplyEqualizer(sampleCount, samples);
}
double SoundMixer::GetRateAdjustment()
{
return _resampler->GetRateAdjustment();
}

View file

@ -2,18 +2,29 @@
#include "stdafx.h"
#include "IAudioDevice.h"
class Console;
class Equalizer;
class SoundResampler;
class SoundMixer
{
private:
IAudioDevice* _audioDevice;
uint32_t _sampleRate;
IAudioDevice *_audioDevice;
Console *_console;
unique_ptr<Equalizer> _equalizer;
unique_ptr<SoundResampler> _resampler;
int16_t *_sampleBuffer = nullptr;
void ProcessEqualizer(int16_t *samples, uint32_t sampleCount);
public:
SoundMixer();
SoundMixer(Console *console);
~SoundMixer();
void PlayAudioBuffer(int16_t *samples, uint32_t sampleCount);
void StopAudio(bool clearBuffer = false);
void RegisterAudioDevice(IAudioDevice *audioDevice);
AudioStatistics GetStatistics();
double GetRateAdjustment();
};

107
Core/SoundResampler.cpp Normal file
View file

@ -0,0 +1,107 @@
#include "stdafx.h"
#include "SoundResampler.h"
#include "Console.h"
#include "EmuSettings.h"
#include "SoundMixer.h"
#include "../Utilities/blip_buf.h"
SoundResampler::SoundResampler(Console *console)
{
_console = console;
_blipBufLeft = blip_new(SoundResampler::SpcSampleRate);
_blipBufRight = blip_new(SoundResampler::SpcSampleRate);
}
SoundResampler::~SoundResampler()
{
blip_delete(_blipBufLeft);
blip_delete(_blipBufRight);
}
double SoundResampler::GetRateAdjustment()
{
return _rateAdjustment;
}
double SoundResampler::GetTargetRateAdjustment()
{
AudioConfig cfg = _console->GetSettings()->GetAudioConfig();
bool isRecording = false; //TODO _waveRecorder || _console->GetVideoRenderer()->IsRecording();
if(!isRecording && !cfg.DisableDynamicSampleRate) {
//Don't deviate from selected sample rate while recording
//TODO: Have 2 output streams (one for recording, one for the speakers)
AudioStatistics stats = _console->GetSoundMixer()->GetStatistics();
if(stats.AverageLatency > 0 && _console->GetSettings()->GetEmulationSpeed() == 100) {
//Try to stay within +/- 3ms of requested latency
constexpr int32_t maxGap = 3;
constexpr int32_t maxSubAdjustment = 3600;
int32_t requestedLatency = (int32_t)cfg.AudioLatency;
double latencyGap = stats.AverageLatency - requestedLatency;
double adjustment = std::min(0.0025, (std::ceil((std::abs(latencyGap) - maxGap) * 8)) * 0.00003125);
if(latencyGap < 0 && _underTarget < maxSubAdjustment) {
_underTarget++;
} else if(latencyGap > 0 && _underTarget > -maxSubAdjustment) {
_underTarget--;
}
//For every ~1 second spent under/over target latency, further adjust rate (GetTargetRate is called approx. 3x per frame)
//This should slowly get us closer to the actual output rate of the sound card
double subAdjustment = 0.00003125 * _underTarget / 180;
if(adjustment > 0) {
if(latencyGap > maxGap) {
_rateAdjustment = 1 - adjustment + subAdjustment;
} else if(latencyGap < -maxGap) {
_rateAdjustment = 1 + adjustment + subAdjustment;
}
} else if(std::abs(latencyGap) < 1) {
//Restore normal rate once we get within +/- 1ms
_rateAdjustment = 1.0 + subAdjustment;
}
} else {
_underTarget = 0;
_rateAdjustment = 1.0;
}
} else {
_underTarget = 0;
_rateAdjustment = 1.0;
}
return _rateAdjustment;
}
void SoundResampler::UpdateTargetSampleRate(uint32_t sampleRate)
{
double targetRate = sampleRate * GetTargetRateAdjustment();
if(targetRate != _previousTargetRate) {
blip_set_rates(_blipBufLeft, SoundResampler::SpcSampleRate, targetRate);
blip_set_rates(_blipBufRight, SoundResampler::SpcSampleRate, targetRate);
_previousTargetRate = targetRate;
}
}
uint32_t SoundResampler::Resample(int16_t *inSamples, uint32_t sampleCount, uint32_t sampleRate, int16_t *outSamples)
{
UpdateTargetSampleRate(sampleRate);
blip_add_delta(_blipBufLeft, 0, inSamples[0] - _lastSampleLeft);
blip_add_delta(_blipBufRight, 0, inSamples[1] - _lastSampleRight);
for(uint32_t i = 1; i < sampleCount; i++) {
blip_add_delta(_blipBufLeft, i, inSamples[i * 2] - inSamples[i * 2 - 2]);
blip_add_delta(_blipBufRight, i, inSamples[i * 2 + 1] - inSamples[i * 2 - 1]);
}
_lastSampleLeft = inSamples[(sampleCount - 1) * 2];
_lastSampleRight = inSamples[(sampleCount - 1) * 2 + 1];
blip_end_frame(_blipBufLeft, sampleCount);
blip_end_frame(_blipBufRight, sampleCount);
uint32_t resampledCount = blip_read_samples(_blipBufLeft, outSamples, SoundResampler::SpcSampleRate, true);
blip_read_samples(_blipBufRight, outSamples + 1, SoundResampler::SpcSampleRate, true);
return resampledCount;
}

34
Core/SoundResampler.h Normal file
View file

@ -0,0 +1,34 @@
#pragma once
#include "stdafx.h"
class Console;
struct blip_t;
class SoundResampler
{
public:
static constexpr int SpcSampleRate = 32000;
private:
Console *_console;
double _rateAdjustment = 1.0;
double _previousTargetRate = 0;
int32_t _underTarget = 0;
blip_t *_blipBufLeft = nullptr;
blip_t *_blipBufRight = nullptr;
int16_t _lastSampleLeft = 0;
int16_t _lastSampleRight = 0;
double GetTargetRateAdjustment();
void UpdateTargetSampleRate(uint32_t sampleRate);
public:
SoundResampler(Console *console);
~SoundResampler();
double GetRateAdjustment();
uint32_t Resample(int16_t *inSamples, uint32_t sampleCount, uint32_t sampleRate, int16_t *outSamples);
};

View file

@ -1,13 +1,27 @@
#include "stdafx.h"
#include "../Core/Console.h"
#include "../Core/IAudioDevice.h"
#include "../Core/EmuSettings.h"
#include "../Core/SettingTypes.h"
extern shared_ptr<Console> _console;
extern unique_ptr<IAudioDevice> _soundManager;
static string _returnString;
extern "C" {
DllExport void __stdcall SetVideoConfig(VideoConfig config)
{
_console->GetSettings()->SetVideoConfig(config);
}
DllExport void __stdcall SetAudioConfig(AudioConfig config)
{
_console->GetSettings()->SetAudioConfig(config);
}
DllExport const char* __stdcall GetAudioDevices()
{
_returnString = _soundManager ? _soundManager->GetAvailableDevices() : "";
return _returnString.c_str();
}
}

53
UI/Config/AudioConfig.cs Normal file
View file

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Mesen.GUI.Config
{
[StructLayout(LayoutKind.Sequential)]
public class AudioConfig : BaseConfig<AudioConfig>
{
[MarshalAs(UnmanagedType.LPStr)] public string AudioDevice = "";
[MarshalAs(UnmanagedType.I1)] public bool EnableAudio = true;
[MarshalAs(UnmanagedType.I1)] public bool DisableDynamicSampleRate = false;
[MinMax(0, 100)] public UInt32 MasterVolume = 25;
[ValidValues(11025, 22050, 44100, 48000, 96000)] public UInt32 SampleRate = 48000;
[MinMax(15, 300)] public UInt32 AudioLatency = 60;
[MarshalAs(UnmanagedType.I1)] public bool MuteSoundInBackground = false;
[MarshalAs(UnmanagedType.I1)] public bool ReduceSoundInBackground = true;
[MarshalAs(UnmanagedType.I1)] public bool ReduceSoundInFastForward = false;
[MinMax(0, 100)] public int VolumeReduction = 75;
[MarshalAs(UnmanagedType.I1)] public bool EnableEqualizer = false;
[MinMax(-20.0, 20.0)] public double Band1Gain = 0;
[MinMax(-20.0, 20.0)] public double Band2Gain = 0;
[MinMax(-20.0, 20.0)] public double Band3Gain = 0;
[MinMax(-20.0, 20.0)] public double Band4Gain = 0;
[MinMax(-20.0, 20.0)] public double Band5Gain = 0;
[MinMax(-20.0, 20.0)] public double Band6Gain = 0;
[MinMax(-20.0, 20.0)] public double Band7Gain = 0;
[MinMax(-20.0, 20.0)] public double Band8Gain = 0;
[MinMax(-20.0, 20.0)] public double Band9Gain = 0;
[MinMax(-20.0, 20.0)] public double Band10Gain = 0;
[MinMax(-20.0, 20.0)] public double Band11Gain = 0;
[MinMax(-20.0, 20.0)] public double Band12Gain = 0;
[MinMax(-20.0, 20.0)] public double Band13Gain = 0;
[MinMax(-20.0, 20.0)] public double Band14Gain = 0;
[MinMax(-20.0, 20.0)] public double Band15Gain = 0;
[MinMax(-20.0, 20.0)] public double Band16Gain = 0;
[MinMax(-20.0, 20.0)] public double Band17Gain = 0;
[MinMax(-20.0, 20.0)] public double Band18Gain = 0;
[MinMax(-20.0, 20.0)] public double Band19Gain = 0;
[MinMax(-20.0, 20.0)] public double Band20Gain = 0;
public void ApplyConfig()
{
ConfigApi.SetAudioConfig(this);
}
}
}

View file

@ -18,6 +18,7 @@ namespace Mesen.GUI.Config
public string Version = "0.1.0";
public List<RecentItem> RecentFiles;
public VideoConfig Video;
public AudioConfig Audio;
public DebugInfo Debug;
public Point? WindowLocation;
public Size? WindowSize;
@ -27,6 +28,7 @@ namespace Mesen.GUI.Config
RecentFiles = new List<RecentItem>();
Debug = new DebugInfo();
Video = new VideoConfig();
Audio = new AudioConfig();
}
~Configuration()
@ -53,6 +55,7 @@ namespace Mesen.GUI.Config
public void ApplyConfig()
{
Video.ApplyConfig();
Audio.ApplyConfig();
}
public void InitializeDefaults()

View file

@ -27,6 +27,24 @@ namespace Mesen.GUI.Controls
}
}
public int TickFrequency
{
get { return trackBar.TickFrequency; }
set { trackBar.TickFrequency = value; }
}
public int SmallChange
{
get { return trackBar.SmallChange; }
set { trackBar.SmallChange = value; }
}
public int LargeChange
{
get { return trackBar.LargeChange; }
set { trackBar.LargeChange = value; }
}
public int Minimum
{
get { return trackBar.Minimum; }
@ -38,7 +56,9 @@ namespace Mesen.GUI.Controls
get { return trackBar.Maximum; }
set { trackBar.Maximum = value; }
}
public int Multiplier { get; set; } = 1;
[Bindable(true)]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
@ -51,10 +71,10 @@ namespace Mesen.GUI.Controls
public int Value
{
get { return trackBar.Value; }
get { return trackBar.Value * Multiplier; }
set
{
trackBar.Value = value;
trackBar.Value = value / Multiplier;
UpdateText();
}
}
@ -64,7 +84,7 @@ namespace Mesen.GUI.Controls
if(this.Minimum == 0) {
lblValue.Text = trackBar.Value.ToString() + "%";
} else {
lblValue.Text = (trackBar.Value / 10.0).ToString() + "dB";
lblValue.Text = (trackBar.Value / (double)Multiplier).ToString() + "dB";
lblValue.Font = new Font("Microsoft Sans Serif", 6.75F);
}
}

992
UI/Forms/Config/frmAudioConfig.Designer.cs generated Normal file
View file

@ -0,0 +1,992 @@
namespace Mesen.GUI.Forms.Config
{
partial class frmAudioConfig
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tpgGeneral = new System.Windows.Forms.TabPage();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.lblVolumeReductionSettings = new System.Windows.Forms.Label();
this.chkEnableAudio = new System.Windows.Forms.CheckBox();
this.lblSampleRate = new System.Windows.Forms.Label();
this.lblAudioLatency = new System.Windows.Forms.Label();
this.cboSampleRate = new System.Windows.Forms.ComboBox();
this.lblAudioDevice = new System.Windows.Forms.Label();
this.cboAudioDevice = new System.Windows.Forms.ComboBox();
this.tableLayoutPanel7 = new System.Windows.Forms.TableLayoutPanel();
this.lblLatencyWarning = new System.Windows.Forms.Label();
this.picLatencyWarning = new System.Windows.Forms.PictureBox();
this.lblLatencyMs = new System.Windows.Forms.Label();
this.nudLatency = new Mesen.GUI.Controls.MesenNumericUpDown();
this.tableLayoutPanel8 = new System.Windows.Forms.TableLayoutPanel();
this.chkReduceSoundInBackground = new System.Windows.Forms.CheckBox();
this.chkReduceSoundInFastForward = new System.Windows.Forms.CheckBox();
this.trkVolumeReduction = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.chkMuteSoundInBackground = new System.Windows.Forms.CheckBox();
this.trkMaster = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.lblVolume = new System.Windows.Forms.Label();
this.tpgEqualizer = new System.Windows.Forms.TabPage();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.chkEnableEqualizer = new System.Windows.Forms.CheckBox();
this.tlpEqualizer = new System.Windows.Forms.TableLayoutPanel();
this.trkBand6Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand5Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand4Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand3Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand2Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand1Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand11Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand12Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand13Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand14Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand15Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand16Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand7Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand8Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand9Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand10Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand17Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand18Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand19Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkBand20Gain = new Mesen.GUI.Controls.ctrlTrackbar();
this.tpgAdvanced = new System.Windows.Forms.TabPage();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.chkDisableDynamicSampleRate = new Mesen.GUI.Controls.ctrlRiskyOption();
this.tabControl1.SuspendLayout();
this.tpgGeneral.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.tableLayoutPanel7.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picLatencyWarning)).BeginInit();
this.tableLayoutPanel8.SuspendLayout();
this.tpgEqualizer.SuspendLayout();
this.groupBox1.SuspendLayout();
this.tlpEqualizer.SuspendLayout();
this.tpgAdvanced.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
this.SuspendLayout();
//
// baseConfigPanel
//
this.baseConfigPanel.Location = new System.Drawing.Point(0, 378);
this.baseConfigPanel.Size = new System.Drawing.Size(492, 29);
//
// tabControl1
//
this.tabControl1.Controls.Add(this.tpgGeneral);
this.tabControl1.Controls.Add(this.tpgEqualizer);
this.tabControl1.Controls.Add(this.tpgAdvanced);
this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControl1.Location = new System.Drawing.Point(0, 0);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(492, 378);
this.tabControl1.TabIndex = 2;
//
// tpgGeneral
//
this.tpgGeneral.Controls.Add(this.tableLayoutPanel2);
this.tpgGeneral.Location = new System.Drawing.Point(4, 22);
this.tpgGeneral.Name = "tpgGeneral";
this.tpgGeneral.Padding = new System.Windows.Forms.Padding(3);
this.tpgGeneral.Size = new System.Drawing.Size(484, 352);
this.tpgGeneral.TabIndex = 2;
this.tpgGeneral.Text = "General";
this.tpgGeneral.UseVisualStyleBackColor = true;
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 2;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel2.Controls.Add(this.lblVolumeReductionSettings, 0, 5);
this.tableLayoutPanel2.Controls.Add(this.chkEnableAudio, 0, 0);
this.tableLayoutPanel2.Controls.Add(this.lblSampleRate, 0, 2);
this.tableLayoutPanel2.Controls.Add(this.lblAudioLatency, 0, 3);
this.tableLayoutPanel2.Controls.Add(this.cboSampleRate, 1, 2);
this.tableLayoutPanel2.Controls.Add(this.lblAudioDevice, 0, 1);
this.tableLayoutPanel2.Controls.Add(this.cboAudioDevice, 1, 1);
this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel7, 1, 3);
this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel8, 0, 6);
this.tableLayoutPanel2.Controls.Add(this.trkMaster, 1, 4);
this.tableLayoutPanel2.Controls.Add(this.lblVolume, 0, 4);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 3);
this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 10;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 22F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(478, 346);
this.tableLayoutPanel2.TabIndex = 3;
//
// lblVolumeReductionSettings
//
this.lblVolumeReductionSettings.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.lblVolumeReductionSettings.AutoSize = true;
this.tableLayoutPanel2.SetColumnSpan(this.lblVolumeReductionSettings, 2);
this.lblVolumeReductionSettings.ForeColor = System.Drawing.SystemColors.GrayText;
this.lblVolumeReductionSettings.Location = new System.Drawing.Point(0, 174);
this.lblVolumeReductionSettings.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
this.lblVolumeReductionSettings.Name = "lblVolumeReductionSettings";
this.lblVolumeReductionSettings.Size = new System.Drawing.Size(94, 13);
this.lblVolumeReductionSettings.TabIndex = 24;
this.lblVolumeReductionSettings.Text = "Volume Reduction";
this.lblVolumeReductionSettings.Visible = false;
//
// chkEnableAudio
//
this.chkEnableAudio.AutoSize = true;
this.tableLayoutPanel2.SetColumnSpan(this.chkEnableAudio, 2);
this.chkEnableAudio.Location = new System.Drawing.Point(6, 6);
this.chkEnableAudio.Margin = new System.Windows.Forms.Padding(6, 6, 6, 3);
this.chkEnableAudio.Name = "chkEnableAudio";
this.chkEnableAudio.Size = new System.Drawing.Size(89, 17);
this.chkEnableAudio.TabIndex = 3;
this.chkEnableAudio.Text = "Enable Audio";
this.chkEnableAudio.UseVisualStyleBackColor = true;
//
// lblSampleRate
//
this.lblSampleRate.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblSampleRate.AutoSize = true;
this.lblSampleRate.Location = new System.Drawing.Point(3, 60);
this.lblSampleRate.Name = "lblSampleRate";
this.lblSampleRate.Size = new System.Drawing.Size(71, 13);
this.lblSampleRate.TabIndex = 0;
this.lblSampleRate.Text = "Sample Rate:";
//
// lblAudioLatency
//
this.lblAudioLatency.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblAudioLatency.AutoSize = true;
this.lblAudioLatency.Location = new System.Drawing.Point(3, 87);
this.lblAudioLatency.Name = "lblAudioLatency";
this.lblAudioLatency.Size = new System.Drawing.Size(48, 13);
this.lblAudioLatency.TabIndex = 0;
this.lblAudioLatency.Text = "Latency:";
//
// cboSampleRate
//
this.cboSampleRate.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cboSampleRate.FormattingEnabled = true;
this.cboSampleRate.Items.AddRange(new object[] {
"11,025 Hz",
"22,050 Hz",
"32,000 Hz",
"44,100 Hz",
"48,000 Hz",
"96,000 Hz"});
this.cboSampleRate.Location = new System.Drawing.Point(80, 56);
this.cboSampleRate.Name = "cboSampleRate";
this.cboSampleRate.Size = new System.Drawing.Size(75, 21);
this.cboSampleRate.TabIndex = 5;
//
// lblAudioDevice
//
this.lblAudioDevice.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblAudioDevice.AutoSize = true;
this.lblAudioDevice.Location = new System.Drawing.Point(3, 33);
this.lblAudioDevice.Name = "lblAudioDevice";
this.lblAudioDevice.Size = new System.Drawing.Size(44, 13);
this.lblAudioDevice.TabIndex = 6;
this.lblAudioDevice.Text = "Device:";
//
// cboAudioDevice
//
this.cboAudioDevice.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cboAudioDevice.FormattingEnabled = true;
this.cboAudioDevice.Location = new System.Drawing.Point(80, 29);
this.cboAudioDevice.Name = "cboAudioDevice";
this.cboAudioDevice.Size = new System.Drawing.Size(209, 21);
this.cboAudioDevice.TabIndex = 7;
//
// tableLayoutPanel7
//
this.tableLayoutPanel7.AutoSize = true;
this.tableLayoutPanel7.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.tableLayoutPanel7.ColumnCount = 4;
this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel7.Controls.Add(this.lblLatencyWarning, 3, 0);
this.tableLayoutPanel7.Controls.Add(this.picLatencyWarning, 2, 0);
this.tableLayoutPanel7.Controls.Add(this.lblLatencyMs, 1, 0);
this.tableLayoutPanel7.Controls.Add(this.nudLatency, 0, 0);
this.tableLayoutPanel7.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel7.Location = new System.Drawing.Point(77, 80);
this.tableLayoutPanel7.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel7.Name = "tableLayoutPanel7";
this.tableLayoutPanel7.RowCount = 1;
this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel7.Size = new System.Drawing.Size(401, 27);
this.tableLayoutPanel7.TabIndex = 15;
//
// lblLatencyWarning
//
this.lblLatencyWarning.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblLatencyWarning.AutoSize = true;
this.lblLatencyWarning.Location = new System.Drawing.Point(98, 7);
this.lblLatencyWarning.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
this.lblLatencyWarning.Name = "lblLatencyWarning";
this.lblLatencyWarning.Size = new System.Drawing.Size(192, 13);
this.lblLatencyWarning.TabIndex = 4;
this.lblLatencyWarning.Text = "Low values may cause sound problems";
this.lblLatencyWarning.Visible = false;
//
// picLatencyWarning
//
this.picLatencyWarning.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.picLatencyWarning.BackgroundImage = global::Mesen.GUI.Properties.Resources.Warning;
this.picLatencyWarning.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
this.picLatencyWarning.Location = new System.Drawing.Point(82, 5);
this.picLatencyWarning.Margin = new System.Windows.Forms.Padding(5, 3, 0, 3);
this.picLatencyWarning.Name = "picLatencyWarning";
this.picLatencyWarning.Size = new System.Drawing.Size(16, 16);
this.picLatencyWarning.TabIndex = 3;
this.picLatencyWarning.TabStop = false;
this.picLatencyWarning.Visible = false;
//
// lblLatencyMs
//
this.lblLatencyMs.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblLatencyMs.AutoSize = true;
this.lblLatencyMs.Location = new System.Drawing.Point(54, 7);
this.lblLatencyMs.Name = "lblLatencyMs";
this.lblLatencyMs.Size = new System.Drawing.Size(20, 13);
this.lblLatencyMs.TabIndex = 2;
this.lblLatencyMs.Text = "ms";
//
// nudLatency
//
this.nudLatency.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.nudLatency.DecimalPlaces = 0;
this.nudLatency.Increment = new decimal(new int[] {
1,
0,
0,
0});
this.nudLatency.Location = new System.Drawing.Point(3, 3);
this.nudLatency.Maximum = new decimal(new int[] {
300,
0,
0,
0});
this.nudLatency.MaximumSize = new System.Drawing.Size(10000, 20);
this.nudLatency.Minimum = new decimal(new int[] {
15,
0,
0,
0});
this.nudLatency.MinimumSize = new System.Drawing.Size(0, 21);
this.nudLatency.Name = "nudLatency";
this.nudLatency.Size = new System.Drawing.Size(45, 21);
this.nudLatency.TabIndex = 1;
this.nudLatency.Value = new decimal(new int[] {
100,
0,
0,
0});
//
// tableLayoutPanel8
//
this.tableLayoutPanel8.ColumnCount = 2;
this.tableLayoutPanel2.SetColumnSpan(this.tableLayoutPanel8, 2);
this.tableLayoutPanel8.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel8.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel8.Controls.Add(this.chkReduceSoundInBackground, 0, 1);
this.tableLayoutPanel8.Controls.Add(this.chkReduceSoundInFastForward, 0, 2);
this.tableLayoutPanel8.Controls.Add(this.trkVolumeReduction, 1, 1);
this.tableLayoutPanel8.Controls.Add(this.chkMuteSoundInBackground, 0, 0);
this.tableLayoutPanel8.Location = new System.Drawing.Point(10, 190);
this.tableLayoutPanel8.Margin = new System.Windows.Forms.Padding(10, 3, 0, 0);
this.tableLayoutPanel8.Name = "tableLayoutPanel8";
this.tableLayoutPanel8.RowCount = 4;
this.tableLayoutPanel8.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel8.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel8.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel8.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel8.Size = new System.Drawing.Size(453, 81);
this.tableLayoutPanel8.TabIndex = 25;
this.tableLayoutPanel8.Visible = false;
//
// chkReduceSoundInBackground
//
this.chkReduceSoundInBackground.AutoSize = true;
this.chkReduceSoundInBackground.Location = new System.Drawing.Point(3, 26);
this.chkReduceSoundInBackground.Name = "chkReduceSoundInBackground";
this.chkReduceSoundInBackground.Size = new System.Drawing.Size(164, 17);
this.chkReduceSoundInBackground.TabIndex = 13;
this.chkReduceSoundInBackground.Text = "Reduce when in background";
this.chkReduceSoundInBackground.UseVisualStyleBackColor = true;
//
// chkReduceSoundInFastForward
//
this.chkReduceSoundInFastForward.AutoSize = true;
this.chkReduceSoundInFastForward.Location = new System.Drawing.Point(3, 49);
this.chkReduceSoundInFastForward.Name = "chkReduceSoundInFastForward";
this.chkReduceSoundInFastForward.Size = new System.Drawing.Size(225, 17);
this.chkReduceSoundInFastForward.TabIndex = 16;
this.chkReduceSoundInFastForward.Text = "Reduce when fast forwarding or rewinding";
this.chkReduceSoundInFastForward.UseVisualStyleBackColor = true;
//
// trkVolumeReduction
//
this.trkVolumeReduction.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkVolumeReduction.Enabled = false;
this.trkVolumeReduction.Location = new System.Drawing.Point(231, 23);
this.trkVolumeReduction.Margin = new System.Windows.Forms.Padding(0);
this.trkVolumeReduction.Maximum = 100;
this.trkVolumeReduction.MaximumSize = new System.Drawing.Size(400, 55);
this.trkVolumeReduction.Minimum = 0;
this.trkVolumeReduction.MinimumSize = new System.Drawing.Size(150, 55);
this.trkVolumeReduction.Name = "trkVolumeReduction";
this.tableLayoutPanel8.SetRowSpan(this.trkVolumeReduction, 2);
this.trkVolumeReduction.Size = new System.Drawing.Size(222, 55);
this.trkVolumeReduction.TabIndex = 17;
this.trkVolumeReduction.Text = "Volume Reduction";
this.trkVolumeReduction.Value = 50;
//
// chkMuteSoundInBackground
//
this.chkMuteSoundInBackground.AutoSize = true;
this.chkMuteSoundInBackground.Location = new System.Drawing.Point(3, 3);
this.chkMuteSoundInBackground.Name = "chkMuteSoundInBackground";
this.chkMuteSoundInBackground.Size = new System.Drawing.Size(182, 17);
this.chkMuteSoundInBackground.TabIndex = 18;
this.chkMuteSoundInBackground.Text = "Mute sound when in background";
this.chkMuteSoundInBackground.UseVisualStyleBackColor = true;
//
// trkMaster
//
this.trkMaster.Location = new System.Drawing.Point(77, 110);
this.trkMaster.Margin = new System.Windows.Forms.Padding(0, 3, 0, 0);
this.trkMaster.Maximum = 100;
this.trkMaster.MaximumSize = new System.Drawing.Size(400, 55);
this.trkMaster.Minimum = 0;
this.trkMaster.MinimumSize = new System.Drawing.Size(150, 55);
this.trkMaster.Name = "trkMaster";
this.trkMaster.Size = new System.Drawing.Size(222, 55);
this.trkMaster.TabIndex = 26;
this.trkMaster.Text = "Master";
this.trkMaster.Value = 50;
//
// lblVolume
//
this.lblVolume.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblVolume.AutoSize = true;
this.lblVolume.Location = new System.Drawing.Point(3, 129);
this.lblVolume.Name = "lblVolume";
this.lblVolume.Size = new System.Drawing.Size(45, 13);
this.lblVolume.TabIndex = 27;
this.lblVolume.Text = "Volume:";
//
// tpgEqualizer
//
this.tpgEqualizer.Controls.Add(this.groupBox1);
this.tpgEqualizer.Location = new System.Drawing.Point(4, 22);
this.tpgEqualizer.Name = "tpgEqualizer";
this.tpgEqualizer.Padding = new System.Windows.Forms.Padding(3);
this.tpgEqualizer.Size = new System.Drawing.Size(484, 352);
this.tpgEqualizer.TabIndex = 6;
this.tpgEqualizer.Text = "Equalizer";
this.tpgEqualizer.UseVisualStyleBackColor = true;
//
// groupBox1
//
this.groupBox1.Controls.Add(this.chkEnableEqualizer);
this.groupBox1.Controls.Add(this.tlpEqualizer);
this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.groupBox1.Location = new System.Drawing.Point(3, 3);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(478, 346);
this.groupBox1.TabIndex = 4;
this.groupBox1.TabStop = false;
//
// chkEnableEqualizer
//
this.chkEnableEqualizer.AutoSize = true;
this.chkEnableEqualizer.BackColor = System.Drawing.SystemColors.ControlLightLight;
this.chkEnableEqualizer.Location = new System.Drawing.Point(7, 0);
this.chkEnableEqualizer.Name = "chkEnableEqualizer";
this.chkEnableEqualizer.Padding = new System.Windows.Forms.Padding(5, 0, 0, 0);
this.chkEnableEqualizer.Size = new System.Drawing.Size(110, 17);
this.chkEnableEqualizer.TabIndex = 5;
this.chkEnableEqualizer.Text = "Enable Equalizer";
this.chkEnableEqualizer.UseVisualStyleBackColor = false;
this.chkEnableEqualizer.CheckedChanged += new System.EventHandler(this.chkEnableEqualizer_CheckedChanged);
//
// tlpEqualizer
//
this.tlpEqualizer.ColumnCount = 10;
this.tlpEqualizer.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tlpEqualizer.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tlpEqualizer.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tlpEqualizer.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tlpEqualizer.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tlpEqualizer.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tlpEqualizer.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tlpEqualizer.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tlpEqualizer.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tlpEqualizer.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 10F));
this.tlpEqualizer.Controls.Add(this.trkBand6Gain, 5, 0);
this.tlpEqualizer.Controls.Add(this.trkBand5Gain, 4, 0);
this.tlpEqualizer.Controls.Add(this.trkBand4Gain, 3, 0);
this.tlpEqualizer.Controls.Add(this.trkBand3Gain, 2, 0);
this.tlpEqualizer.Controls.Add(this.trkBand2Gain, 1, 0);
this.tlpEqualizer.Controls.Add(this.trkBand1Gain, 0, 0);
this.tlpEqualizer.Controls.Add(this.trkBand11Gain, 0, 1);
this.tlpEqualizer.Controls.Add(this.trkBand12Gain, 1, 1);
this.tlpEqualizer.Controls.Add(this.trkBand13Gain, 2, 1);
this.tlpEqualizer.Controls.Add(this.trkBand14Gain, 3, 1);
this.tlpEqualizer.Controls.Add(this.trkBand15Gain, 4, 1);
this.tlpEqualizer.Controls.Add(this.trkBand16Gain, 5, 1);
this.tlpEqualizer.Controls.Add(this.trkBand7Gain, 6, 0);
this.tlpEqualizer.Controls.Add(this.trkBand8Gain, 7, 0);
this.tlpEqualizer.Controls.Add(this.trkBand9Gain, 8, 0);
this.tlpEqualizer.Controls.Add(this.trkBand10Gain, 9, 0);
this.tlpEqualizer.Controls.Add(this.trkBand17Gain, 6, 1);
this.tlpEqualizer.Controls.Add(this.trkBand18Gain, 7, 1);
this.tlpEqualizer.Controls.Add(this.trkBand19Gain, 8, 1);
this.tlpEqualizer.Controls.Add(this.trkBand20Gain, 9, 1);
this.tlpEqualizer.Dock = System.Windows.Forms.DockStyle.Fill;
this.tlpEqualizer.Enabled = false;
this.tlpEqualizer.Location = new System.Drawing.Point(3, 16);
this.tlpEqualizer.Name = "tlpEqualizer";
this.tlpEqualizer.RowCount = 2;
this.tlpEqualizer.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpEqualizer.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpEqualizer.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tlpEqualizer.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tlpEqualizer.Size = new System.Drawing.Size(472, 327);
this.tlpEqualizer.TabIndex = 3;
//
// trkBand6Gain
//
this.trkBand6Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand6Gain.LargeChange = 10;
this.trkBand6Gain.Location = new System.Drawing.Point(235, 0);
this.trkBand6Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand6Gain.Maximum = 200;
this.trkBand6Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand6Gain.Minimum = -200;
this.trkBand6Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand6Gain.Multiplier = 10;
this.trkBand6Gain.Name = "trkBand6Gain";
this.trkBand6Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand6Gain.SmallChange = 1;
this.trkBand6Gain.TabIndex = 16;
this.trkBand6Gain.Text = "225 Hz";
this.trkBand6Gain.TickFrequency = 20;
this.trkBand6Gain.Value = 500;
//
// trkBand5Gain
//
this.trkBand5Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand5Gain.LargeChange = 10;
this.trkBand5Gain.Location = new System.Drawing.Point(188, 0);
this.trkBand5Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand5Gain.Maximum = 200;
this.trkBand5Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand5Gain.Minimum = -200;
this.trkBand5Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand5Gain.Multiplier = 10;
this.trkBand5Gain.Name = "trkBand5Gain";
this.trkBand5Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand5Gain.SmallChange = 1;
this.trkBand5Gain.TabIndex = 15;
this.trkBand5Gain.Text = "160 Hz";
this.trkBand5Gain.TickFrequency = 20;
this.trkBand5Gain.Value = 500;
//
// trkBand4Gain
//
this.trkBand4Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand4Gain.LargeChange = 10;
this.trkBand4Gain.Location = new System.Drawing.Point(141, 0);
this.trkBand4Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand4Gain.Maximum = 200;
this.trkBand4Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand4Gain.Minimum = -200;
this.trkBand4Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand4Gain.Multiplier = 10;
this.trkBand4Gain.Name = "trkBand4Gain";
this.trkBand4Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand4Gain.SmallChange = 1;
this.trkBand4Gain.TabIndex = 14;
this.trkBand4Gain.Text = "113 Hz";
this.trkBand4Gain.TickFrequency = 20;
this.trkBand4Gain.Value = 500;
//
// trkBand3Gain
//
this.trkBand3Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand3Gain.LargeChange = 10;
this.trkBand3Gain.Location = new System.Drawing.Point(94, 0);
this.trkBand3Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand3Gain.Maximum = 200;
this.trkBand3Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand3Gain.Minimum = -200;
this.trkBand3Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand3Gain.Multiplier = 10;
this.trkBand3Gain.Name = "trkBand3Gain";
this.trkBand3Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand3Gain.SmallChange = 1;
this.trkBand3Gain.TabIndex = 13;
this.trkBand3Gain.Text = "80 Hz";
this.trkBand3Gain.TickFrequency = 20;
this.trkBand3Gain.Value = 500;
//
// trkBand2Gain
//
this.trkBand2Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand2Gain.LargeChange = 10;
this.trkBand2Gain.Location = new System.Drawing.Point(47, 0);
this.trkBand2Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand2Gain.Maximum = 200;
this.trkBand2Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand2Gain.Minimum = -200;
this.trkBand2Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand2Gain.Multiplier = 10;
this.trkBand2Gain.Name = "trkBand2Gain";
this.trkBand2Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand2Gain.SmallChange = 1;
this.trkBand2Gain.TabIndex = 12;
this.trkBand2Gain.Text = "56 Hz";
this.trkBand2Gain.TickFrequency = 20;
this.trkBand2Gain.Value = 500;
//
// trkBand1Gain
//
this.trkBand1Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand1Gain.LargeChange = 10;
this.trkBand1Gain.Location = new System.Drawing.Point(0, 0);
this.trkBand1Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand1Gain.Maximum = 200;
this.trkBand1Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand1Gain.Minimum = -200;
this.trkBand1Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand1Gain.Multiplier = 10;
this.trkBand1Gain.Name = "trkBand1Gain";
this.trkBand1Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand1Gain.SmallChange = 1;
this.trkBand1Gain.TabIndex = 11;
this.trkBand1Gain.Text = "40 Hz";
this.trkBand1Gain.TickFrequency = 20;
this.trkBand1Gain.Value = 500;
//
// trkBand11Gain
//
this.trkBand11Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand11Gain.LargeChange = 10;
this.trkBand11Gain.Location = new System.Drawing.Point(0, 160);
this.trkBand11Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand11Gain.Maximum = 200;
this.trkBand11Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand11Gain.Minimum = -200;
this.trkBand11Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand11Gain.Multiplier = 10;
this.trkBand11Gain.Name = "trkBand11Gain";
this.trkBand11Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand11Gain.SmallChange = 1;
this.trkBand11Gain.TabIndex = 17;
this.trkBand11Gain.Text = "1.0 kHz";
this.trkBand11Gain.TickFrequency = 20;
this.trkBand11Gain.Value = 500;
//
// trkBand12Gain
//
this.trkBand12Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand12Gain.LargeChange = 10;
this.trkBand12Gain.Location = new System.Drawing.Point(47, 160);
this.trkBand12Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand12Gain.Maximum = 200;
this.trkBand12Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand12Gain.Minimum = -200;
this.trkBand12Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand12Gain.Multiplier = 10;
this.trkBand12Gain.Name = "trkBand12Gain";
this.trkBand12Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand12Gain.SmallChange = 1;
this.trkBand12Gain.TabIndex = 18;
this.trkBand12Gain.Text = "2.0 kHz";
this.trkBand12Gain.TickFrequency = 20;
this.trkBand12Gain.Value = 500;
//
// trkBand13Gain
//
this.trkBand13Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand13Gain.LargeChange = 10;
this.trkBand13Gain.Location = new System.Drawing.Point(94, 160);
this.trkBand13Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand13Gain.Maximum = 200;
this.trkBand13Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand13Gain.Minimum = -200;
this.trkBand13Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand13Gain.Multiplier = 10;
this.trkBand13Gain.Name = "trkBand13Gain";
this.trkBand13Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand13Gain.SmallChange = 1;
this.trkBand13Gain.TabIndex = 19;
this.trkBand13Gain.Text = "3.0 kHz";
this.trkBand13Gain.TickFrequency = 20;
this.trkBand13Gain.Value = 500;
//
// trkBand14Gain
//
this.trkBand14Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand14Gain.LargeChange = 10;
this.trkBand14Gain.Location = new System.Drawing.Point(141, 160);
this.trkBand14Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand14Gain.Maximum = 200;
this.trkBand14Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand14Gain.Minimum = -200;
this.trkBand14Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand14Gain.Multiplier = 10;
this.trkBand14Gain.Name = "trkBand14Gain";
this.trkBand14Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand14Gain.SmallChange = 1;
this.trkBand14Gain.TabIndex = 20;
this.trkBand14Gain.Text = "4.0 kHz";
this.trkBand14Gain.TickFrequency = 20;
this.trkBand14Gain.Value = 500;
//
// trkBand15Gain
//
this.trkBand15Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand15Gain.LargeChange = 10;
this.trkBand15Gain.Location = new System.Drawing.Point(188, 160);
this.trkBand15Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand15Gain.Maximum = 200;
this.trkBand15Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand15Gain.Minimum = -200;
this.trkBand15Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand15Gain.Multiplier = 10;
this.trkBand15Gain.Name = "trkBand15Gain";
this.trkBand15Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand15Gain.SmallChange = 1;
this.trkBand15Gain.TabIndex = 21;
this.trkBand15Gain.Text = "5.0 kHz";
this.trkBand15Gain.TickFrequency = 20;
this.trkBand15Gain.Value = 500;
//
// trkBand16Gain
//
this.trkBand16Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand16Gain.LargeChange = 10;
this.trkBand16Gain.Location = new System.Drawing.Point(235, 160);
this.trkBand16Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand16Gain.Maximum = 200;
this.trkBand16Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand16Gain.Minimum = -200;
this.trkBand16Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand16Gain.Multiplier = 10;
this.trkBand16Gain.Name = "trkBand16Gain";
this.trkBand16Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand16Gain.SmallChange = 1;
this.trkBand16Gain.TabIndex = 22;
this.trkBand16Gain.Text = "6.0 kHz";
this.trkBand16Gain.TickFrequency = 20;
this.trkBand16Gain.Value = 500;
//
// trkBand7Gain
//
this.trkBand7Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand7Gain.LargeChange = 10;
this.trkBand7Gain.Location = new System.Drawing.Point(282, 0);
this.trkBand7Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand7Gain.Maximum = 200;
this.trkBand7Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand7Gain.Minimum = -200;
this.trkBand7Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand7Gain.Multiplier = 10;
this.trkBand7Gain.Name = "trkBand7Gain";
this.trkBand7Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand7Gain.SmallChange = 1;
this.trkBand7Gain.TabIndex = 23;
this.trkBand7Gain.Text = "320 Hz";
this.trkBand7Gain.TickFrequency = 20;
this.trkBand7Gain.Value = 500;
//
// trkBand8Gain
//
this.trkBand8Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand8Gain.LargeChange = 10;
this.trkBand8Gain.Location = new System.Drawing.Point(329, 0);
this.trkBand8Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand8Gain.Maximum = 200;
this.trkBand8Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand8Gain.Minimum = -200;
this.trkBand8Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand8Gain.Multiplier = 10;
this.trkBand8Gain.Name = "trkBand8Gain";
this.trkBand8Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand8Gain.SmallChange = 1;
this.trkBand8Gain.TabIndex = 24;
this.trkBand8Gain.Text = "450 Hz";
this.trkBand8Gain.TickFrequency = 20;
this.trkBand8Gain.Value = 500;
//
// trkBand9Gain
//
this.trkBand9Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand9Gain.LargeChange = 10;
this.trkBand9Gain.Location = new System.Drawing.Point(376, 0);
this.trkBand9Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand9Gain.Maximum = 200;
this.trkBand9Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand9Gain.Minimum = -200;
this.trkBand9Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand9Gain.Multiplier = 10;
this.trkBand9Gain.Name = "trkBand9Gain";
this.trkBand9Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand9Gain.SmallChange = 1;
this.trkBand9Gain.TabIndex = 25;
this.trkBand9Gain.Text = "600 Hz";
this.trkBand9Gain.TickFrequency = 20;
this.trkBand9Gain.Value = 500;
//
// trkBand10Gain
//
this.trkBand10Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand10Gain.LargeChange = 10;
this.trkBand10Gain.Location = new System.Drawing.Point(423, 0);
this.trkBand10Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand10Gain.Maximum = 200;
this.trkBand10Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand10Gain.Minimum = -200;
this.trkBand10Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand10Gain.Multiplier = 10;
this.trkBand10Gain.Name = "trkBand10Gain";
this.trkBand10Gain.Size = new System.Drawing.Size(49, 160);
this.trkBand10Gain.SmallChange = 1;
this.trkBand10Gain.TabIndex = 26;
this.trkBand10Gain.Text = "750 Hz";
this.trkBand10Gain.TickFrequency = 20;
this.trkBand10Gain.Value = 500;
//
// trkBand17Gain
//
this.trkBand17Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand17Gain.LargeChange = 10;
this.trkBand17Gain.Location = new System.Drawing.Point(282, 160);
this.trkBand17Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand17Gain.Maximum = 200;
this.trkBand17Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand17Gain.Minimum = -200;
this.trkBand17Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand17Gain.Multiplier = 10;
this.trkBand17Gain.Name = "trkBand17Gain";
this.trkBand17Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand17Gain.SmallChange = 1;
this.trkBand17Gain.TabIndex = 27;
this.trkBand17Gain.Text = "7.0 kHz";
this.trkBand17Gain.TickFrequency = 20;
this.trkBand17Gain.Value = 500;
//
// trkBand18Gain
//
this.trkBand18Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand18Gain.LargeChange = 10;
this.trkBand18Gain.Location = new System.Drawing.Point(329, 160);
this.trkBand18Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand18Gain.Maximum = 200;
this.trkBand18Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand18Gain.Minimum = -200;
this.trkBand18Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand18Gain.Multiplier = 10;
this.trkBand18Gain.Name = "trkBand18Gain";
this.trkBand18Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand18Gain.SmallChange = 1;
this.trkBand18Gain.TabIndex = 28;
this.trkBand18Gain.Text = "10.0 kHz";
this.trkBand18Gain.TickFrequency = 20;
this.trkBand18Gain.Value = 500;
//
// trkBand19Gain
//
this.trkBand19Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand19Gain.LargeChange = 10;
this.trkBand19Gain.Location = new System.Drawing.Point(376, 160);
this.trkBand19Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand19Gain.Maximum = 200;
this.trkBand19Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand19Gain.Minimum = -200;
this.trkBand19Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand19Gain.Multiplier = 10;
this.trkBand19Gain.Name = "trkBand19Gain";
this.trkBand19Gain.Size = new System.Drawing.Size(47, 160);
this.trkBand19Gain.SmallChange = 1;
this.trkBand19Gain.TabIndex = 29;
this.trkBand19Gain.Text = "12.5 kHz";
this.trkBand19Gain.TickFrequency = 20;
this.trkBand19Gain.Value = 500;
//
// trkBand20Gain
//
this.trkBand20Gain.Dock = System.Windows.Forms.DockStyle.Fill;
this.trkBand20Gain.LargeChange = 10;
this.trkBand20Gain.Location = new System.Drawing.Point(423, 160);
this.trkBand20Gain.Margin = new System.Windows.Forms.Padding(0);
this.trkBand20Gain.Maximum = 200;
this.trkBand20Gain.MaximumSize = new System.Drawing.Size(63, 160);
this.trkBand20Gain.Minimum = -200;
this.trkBand20Gain.MinimumSize = new System.Drawing.Size(34, 160);
this.trkBand20Gain.Multiplier = 10;
this.trkBand20Gain.Name = "trkBand20Gain";
this.trkBand20Gain.Size = new System.Drawing.Size(49, 160);
this.trkBand20Gain.SmallChange = 1;
this.trkBand20Gain.TabIndex = 30;
this.trkBand20Gain.Text = "15 kHz";
this.trkBand20Gain.TickFrequency = 20;
this.trkBand20Gain.Value = 500;
//
// tpgAdvanced
//
this.tpgAdvanced.Controls.Add(this.tableLayoutPanel1);
this.tpgAdvanced.Location = new System.Drawing.Point(4, 22);
this.tpgAdvanced.Name = "tpgAdvanced";
this.tpgAdvanced.Padding = new System.Windows.Forms.Padding(3);
this.tpgAdvanced.Size = new System.Drawing.Size(484, 352);
this.tpgAdvanced.TabIndex = 7;
this.tpgAdvanced.Text = "Advanced";
this.tpgAdvanced.UseVisualStyleBackColor = true;
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 1;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Controls.Add(this.chkDisableDynamicSampleRate, 0, 0);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 3);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(478, 346);
this.tableLayoutPanel1.TabIndex = 0;
//
// chkDisableDynamicSampleRate
//
this.chkDisableDynamicSampleRate.Checked = false;
this.chkDisableDynamicSampleRate.Location = new System.Drawing.Point(0, 0);
this.chkDisableDynamicSampleRate.Name = "chkDisableDynamicSampleRate";
this.chkDisableDynamicSampleRate.Size = new System.Drawing.Size(463, 24);
this.chkDisableDynamicSampleRate.TabIndex = 5;
this.chkDisableDynamicSampleRate.Text = "Disable dynamic sample rate";
//
// frmAudioConfig
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(492, 407);
this.Controls.Add(this.tabControl1);
this.Name = "frmAudioConfig";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Audio Config";
this.Controls.SetChildIndex(this.baseConfigPanel, 0);
this.Controls.SetChildIndex(this.tabControl1, 0);
this.tabControl1.ResumeLayout(false);
this.tpgGeneral.ResumeLayout(false);
this.tableLayoutPanel2.ResumeLayout(false);
this.tableLayoutPanel2.PerformLayout();
this.tableLayoutPanel7.ResumeLayout(false);
this.tableLayoutPanel7.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.picLatencyWarning)).EndInit();
this.tableLayoutPanel8.ResumeLayout(false);
this.tableLayoutPanel8.PerformLayout();
this.tpgEqualizer.ResumeLayout(false);
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.tlpEqualizer.ResumeLayout(false);
this.tpgAdvanced.ResumeLayout(false);
this.tableLayoutPanel1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tpgGeneral;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.Label lblVolumeReductionSettings;
private System.Windows.Forms.CheckBox chkEnableAudio;
private System.Windows.Forms.Label lblSampleRate;
private System.Windows.Forms.Label lblAudioLatency;
private System.Windows.Forms.ComboBox cboSampleRate;
private System.Windows.Forms.Label lblAudioDevice;
private System.Windows.Forms.ComboBox cboAudioDevice;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel7;
private System.Windows.Forms.Label lblLatencyWarning;
private System.Windows.Forms.PictureBox picLatencyWarning;
private System.Windows.Forms.Label lblLatencyMs;
private Controls.MesenNumericUpDown nudLatency;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel8;
private System.Windows.Forms.CheckBox chkReduceSoundInBackground;
private System.Windows.Forms.CheckBox chkReduceSoundInFastForward;
private Controls.ctrlHorizontalTrackbar trkVolumeReduction;
private System.Windows.Forms.CheckBox chkMuteSoundInBackground;
private System.Windows.Forms.TabPage tpgEqualizer;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.CheckBox chkEnableEqualizer;
private System.Windows.Forms.TableLayoutPanel tlpEqualizer;
private Controls.ctrlTrackbar trkBand6Gain;
private Controls.ctrlTrackbar trkBand5Gain;
private Controls.ctrlTrackbar trkBand4Gain;
private Controls.ctrlTrackbar trkBand3Gain;
private Controls.ctrlTrackbar trkBand2Gain;
private Controls.ctrlTrackbar trkBand1Gain;
private Controls.ctrlTrackbar trkBand11Gain;
private Controls.ctrlTrackbar trkBand12Gain;
private Controls.ctrlTrackbar trkBand13Gain;
private Controls.ctrlTrackbar trkBand14Gain;
private Controls.ctrlTrackbar trkBand15Gain;
private Controls.ctrlTrackbar trkBand16Gain;
private Controls.ctrlTrackbar trkBand7Gain;
private Controls.ctrlTrackbar trkBand8Gain;
private Controls.ctrlTrackbar trkBand9Gain;
private Controls.ctrlTrackbar trkBand10Gain;
private Controls.ctrlTrackbar trkBand17Gain;
private Controls.ctrlTrackbar trkBand18Gain;
private Controls.ctrlTrackbar trkBand19Gain;
private Controls.ctrlTrackbar trkBand20Gain;
private Controls.ctrlHorizontalTrackbar trkMaster;
private System.Windows.Forms.Label lblVolume;
private System.Windows.Forms.TabPage tpgAdvanced;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private Controls.ctrlRiskyOption chkDisableDynamicSampleRate;
}
}

View file

@ -0,0 +1,87 @@
using Mesen.GUI.Config;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Mesen.GUI.Forms.Config
{
public partial class frmAudioConfig : BaseConfigForm
{
public frmAudioConfig()
{
InitializeComponent();
if(this.DesignMode) {
return;
}
cboAudioDevice.Items.AddRange(ConfigApi.GetAudioDevices().ToArray());
Entity = ConfigManager.Config.Audio.Clone();
AddBinding(nameof(AudioConfig.EnableAudio), chkEnableAudio);
AddBinding(nameof(AudioConfig.MasterVolume), trkMaster);
AddBinding(nameof(AudioConfig.AudioLatency), nudLatency);
AddBinding(nameof(AudioConfig.SampleRate), cboSampleRate);
AddBinding(nameof(AudioConfig.AudioDevice), cboAudioDevice);
AddBinding(nameof(AudioConfig.DisableDynamicSampleRate), chkDisableDynamicSampleRate);
AddBinding(nameof(AudioConfig.EnableEqualizer), chkEnableEqualizer);
AddBinding(nameof(AudioConfig.Band1Gain), trkBand1Gain);
AddBinding(nameof(AudioConfig.Band2Gain), trkBand2Gain);
AddBinding(nameof(AudioConfig.Band3Gain), trkBand3Gain);
AddBinding(nameof(AudioConfig.Band4Gain), trkBand4Gain);
AddBinding(nameof(AudioConfig.Band5Gain), trkBand5Gain);
AddBinding(nameof(AudioConfig.Band6Gain), trkBand6Gain);
AddBinding(nameof(AudioConfig.Band7Gain), trkBand7Gain);
AddBinding(nameof(AudioConfig.Band8Gain), trkBand8Gain);
AddBinding(nameof(AudioConfig.Band9Gain), trkBand9Gain);
AddBinding(nameof(AudioConfig.Band10Gain), trkBand10Gain);
AddBinding(nameof(AudioConfig.Band11Gain), trkBand11Gain);
AddBinding(nameof(AudioConfig.Band12Gain), trkBand12Gain);
AddBinding(nameof(AudioConfig.Band13Gain), trkBand13Gain);
AddBinding(nameof(AudioConfig.Band14Gain), trkBand14Gain);
AddBinding(nameof(AudioConfig.Band15Gain), trkBand15Gain);
AddBinding(nameof(AudioConfig.Band16Gain), trkBand16Gain);
AddBinding(nameof(AudioConfig.Band17Gain), trkBand17Gain);
AddBinding(nameof(AudioConfig.Band18Gain), trkBand18Gain);
AddBinding(nameof(AudioConfig.Band19Gain), trkBand19Gain);
AddBinding(nameof(AudioConfig.Band20Gain), trkBand20Gain);
AddBinding(nameof(AudioConfig.ReduceSoundInBackground), chkReduceSoundInBackground);
AddBinding(nameof(AudioConfig.MuteSoundInBackground), chkMuteSoundInBackground);
AddBinding(nameof(AudioConfig.ReduceSoundInFastForward), chkReduceSoundInFastForward);
AddBinding(nameof(AudioConfig.VolumeReduction), trkVolumeReduction);
}
protected override bool ValidateInput()
{
UpdateLatencyWarning();
UpdateObject();
((AudioConfig)this.Entity).ApplyConfig();
return true;
}
private void UpdateLatencyWarning()
{
picLatencyWarning.Visible = nudLatency.Value <= 55;
lblLatencyWarning.Visible = nudLatency.Value <= 55;
}
protected override void OnApply()
{
ConfigManager.Config.Audio = (AudioConfig)this.Entity;
ConfigManager.ApplyChanges();
}
private void chkEnableEqualizer_CheckedChanged(object sender, EventArgs e)
{
tlpEqualizer.Enabled = chkEnableEqualizer.Checked;
}
}
}

View file

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View file

@ -96,7 +96,9 @@ namespace Mesen.GUI.Forms
throw new Exception("No radio button matching value found");
}
} else if(kvp.Value is ctrlTrackbar) {
if(field.FieldType == typeof(Int32)) {
if(field.FieldType == typeof(double)) {
((ctrlTrackbar)kvp.Value).Value = (int)((double)value * 100);
} else if(field.FieldType == typeof(Int32)) {
((ctrlTrackbar)kvp.Value).Value = (int)value;
} else {
((ctrlTrackbar)kvp.Value).Value = (int)(uint)value;
@ -104,6 +106,8 @@ namespace Mesen.GUI.Forms
} else if(kvp.Value is ctrlHorizontalTrackbar) {
if(field.FieldType == typeof(double)) {
((ctrlHorizontalTrackbar)kvp.Value).Value = (int)((double)value * 100);
} else if(field.FieldType == typeof(UInt32)) {
((ctrlHorizontalTrackbar)kvp.Value).Value = (int)(uint)value;
} else {
((ctrlHorizontalTrackbar)kvp.Value).Value = (int)value;
}
@ -234,7 +238,9 @@ namespace Mesen.GUI.Forms
} else if(kvp.Value is Panel) {
field.SetValue(Entity, ((Panel)kvp.Value).Controls.OfType<RadioButton>().FirstOrDefault(r => r.Checked).Tag);
} else if(kvp.Value is ctrlTrackbar) {
if(field.FieldType == typeof(Int32)) {
if(field.FieldType == typeof(double)) {
field.SetValue(Entity, ((ctrlTrackbar)kvp.Value).Value / 100.0);
} else if(field.FieldType == typeof(Int32)) {
field.SetValue(Entity, (Int32)((ctrlTrackbar)kvp.Value).Value);
} else {
field.SetValue(Entity, (UInt32)((ctrlTrackbar)kvp.Value).Value);
@ -242,6 +248,8 @@ namespace Mesen.GUI.Forms
} else if(kvp.Value is ctrlHorizontalTrackbar) {
if(field.FieldType == typeof(double)) {
field.SetValue(Entity, ((ctrlHorizontalTrackbar)kvp.Value).Value / 100.0);
} else if(field.FieldType == typeof(UInt32)) {
field.SetValue(Entity, (UInt32)((ctrlHorizontalTrackbar)kvp.Value).Value);
} else {
field.SetValue(Entity, (Int32)((ctrlHorizontalTrackbar)kvp.Value).Value);
}

View file

@ -44,6 +44,7 @@
this.mnuTilemapViewer = new System.Windows.Forms.ToolStripMenuItem();
this.mnuEventViewer = new System.Windows.Forms.ToolStripMenuItem();
this.pnlRenderer = new System.Windows.Forms.Panel();
this.mnuAudioConfig = new System.Windows.Forms.ToolStripMenuItem();
this.mnuMain.SuspendLayout();
this.pnlRenderer.SuspendLayout();
this.SuspendLayout();
@ -87,6 +88,7 @@
// optionsToolStripMenuItem
//
this.optionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuAudioConfig,
this.mnuVideoConfig});
this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
this.optionsToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
@ -96,7 +98,7 @@
//
this.mnuVideoConfig.Image = global::Mesen.GUI.Properties.Resources.VideoOptions;
this.mnuVideoConfig.Name = "mnuVideoConfig";
this.mnuVideoConfig.Size = new System.Drawing.Size(104, 22);
this.mnuVideoConfig.Size = new System.Drawing.Size(152, 22);
this.mnuVideoConfig.Text = "Video";
this.mnuVideoConfig.Click += new System.EventHandler(this.mnuVideoConfig_Click);
//
@ -195,6 +197,14 @@
this.pnlRenderer.Size = new System.Drawing.Size(512, 448);
this.pnlRenderer.TabIndex = 2;
//
// mnuAudioConfig
//
this.mnuAudioConfig.Image = global::Mesen.GUI.Properties.Resources.Audio;
this.mnuAudioConfig.Name = "mnuAudioConfig";
this.mnuAudioConfig.Size = new System.Drawing.Size(152, 22);
this.mnuAudioConfig.Text = "Audio";
this.mnuAudioConfig.Click += new System.EventHandler(this.mnuAudioConfig_Click);
//
// frmMain
//
this.AllowDrop = true;
@ -233,5 +243,6 @@
private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem mnuVideoConfig;
private System.Windows.Forms.Panel pnlRenderer;
private System.Windows.Forms.ToolStripMenuItem mnuAudioConfig;
}
}

View file

@ -93,6 +93,14 @@ namespace Mesen.GUI.Forms
ConfigManager.Config.Video.ApplyConfig();
}
private void mnuAudioConfig_Click(object sender, EventArgs e)
{
using(frmAudioConfig frm = new frmAudioConfig()) {
frm.ShowDialog(sender, this);
}
ConfigManager.Config.Audio.ApplyConfig();
}
private void mnuDebugger_Click(object sender, EventArgs e)
{
DebugWindowManager.OpenDebugWindow(DebugWindow.Debugger);

View file

@ -17,5 +17,12 @@ namespace Mesen.GUI
private const string DllPath = "MesenSCore.dll";
[DllImport(DllPath)] public static extern void SetVideoConfig(VideoConfig config);
[DllImport(DllPath)] public static extern void SetAudioConfig(AudioConfig config);
[DllImport(DllPath, EntryPoint = "GetAudioDevices")] private static extern IntPtr GetAudioDevicesWrapper();
public static List<string> GetAudioDevices()
{
return new List<string>(Utf8Marshaler.PtrToStringUtf8(ConfigApi.GetAudioDevicesWrapper()).Split(new string[1] { "||" }, StringSplitOptions.RemoveEmptyEntries));
}
}
}

View file

@ -209,6 +209,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="CommandLineHelper.cs" />
<Compile Include="Config\AudioConfig.cs" />
<Compile Include="Config\BaseConfig.cs" />
<Compile Include="Config\ConfigAttributes.cs" />
<Compile Include="Config\Configuration.cs" />
@ -464,6 +465,12 @@
<Compile Include="Forms\BaseInputForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\Config\frmAudioConfig.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\Config\frmAudioConfig.Designer.cs">
<DependentUpon>frmAudioConfig.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Config\frmVideoConfig.cs">
<SubType>Form</SubType>
</Compile>
@ -594,6 +601,9 @@
<EmbeddedResource Include="Forms\BaseInputForm.resx">
<DependentUpon>BaseInputForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Config\frmAudioConfig.resx">
<DependentUpon>frmAudioConfig.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Config\frmVideoConfig.resx">
<DependentUpon>frmVideoConfig.cs</DependentUpon>
</EmbeddedResource>

45
Utilities/Equalizer.cpp Normal file
View file

@ -0,0 +1,45 @@
#include "stdafx.h"
#include "Equalizer.h"
#include "orfanidis_eq.h"
void Equalizer::ApplyEqualizer(uint32_t sampleCount, int16_t *samples)
{
double outL, outR;
for(uint32_t i = 0; i < sampleCount; i++) {
double inL = samples[i * 2];
double inR = samples[i * 2 + 1];
_equalizerLeft->sbs_process(&inL, &outL);
_equalizerRight->sbs_process(&inR, &outR);
samples[i * 2] = (int16_t)outL;
samples[i * 2 + 1] = (int16_t)outR;
}
}
void Equalizer::UpdateEqualizers(vector<double> bandGains, uint32_t sampleRate)
{
if(_prevSampleRate != sampleRate || memcmp(bandGains.data(), _prevEqualizerGains.data(), bandGains.size() * sizeof(double)) != 0) {
vector<double> bands = { 40, 56, 80, 113, 160, 225, 320, 450, 600, 750, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 10000, 12500, 13000 };
bands.insert(bands.begin(), bands[0] - (bands[1] - bands[0]));
bands.insert(bands.end(), bands[bands.size() - 1] + (bands[bands.size() - 1] - bands[bands.size() - 2]));
_eqFrequencyGrid.reset(new orfanidis_eq::freq_grid());
for(size_t i = 1; i < bands.size() - 1; i++) {
_eqFrequencyGrid->add_band((bands[i] + bands[i - 1]) / 2, bands[i], (bands[i + 1] + bands[i]) / 2);
}
_equalizerLeft.reset(new orfanidis_eq::eq1(_eqFrequencyGrid.get(), orfanidis_eq::filter_type::butterworth));
_equalizerRight.reset(new orfanidis_eq::eq1(_eqFrequencyGrid.get(), orfanidis_eq::filter_type::butterworth));
_equalizerLeft->set_sample_rate(sampleRate);
_equalizerRight->set_sample_rate(sampleRate);
for(unsigned int i = 0; i < _eqFrequencyGrid->get_number_of_bands(); i++) {
_equalizerLeft->change_band_gain_db(i, bandGains[i]);
_equalizerRight->change_band_gain_db(i, bandGains[i]);
}
_prevSampleRate = sampleRate;
_prevEqualizerGains = bandGains;
}
}

18
Utilities/Equalizer.h Normal file
View file

@ -0,0 +1,18 @@
#pragma once
#include "stdafx.h"
#include "orfanidis_eq.h"
class Equalizer
{
private:
unique_ptr<orfanidis_eq::freq_grid> _eqFrequencyGrid;
unique_ptr<orfanidis_eq::eq1> _equalizerLeft;
unique_ptr<orfanidis_eq::eq1> _equalizerRight;
uint32_t _prevSampleRate = 0;
vector<double> _prevEqualizerGains;
public:
void ApplyEqualizer(uint32_t sampleCount, int16_t *samples);
void UpdateEqualizers(vector<double> bandGains, uint32_t sampleRate);
};

View file

@ -406,6 +406,7 @@
<ClInclude Include="BpsPatcher.h" />
<ClInclude Include="CamstudioCodec.h" />
<ClInclude Include="CRC32.h" />
<ClInclude Include="Equalizer.h" />
<ClInclude Include="FastString.h" />
<ClInclude Include="FolderUtilities.h" />
<ClInclude Include="HexUtilities.h" />
@ -454,6 +455,7 @@
<ClCompile Include="BpsPatcher.cpp" />
<ClCompile Include="CamstudioCodec.cpp" />
<ClCompile Include="CRC32.cpp" />
<ClCompile Include="Equalizer.cpp" />
<ClCompile Include="FolderUtilities.cpp" />
<ClCompile Include="HexUtilities.cpp" />
<ClCompile Include="HQX\hq2x.cpp">

View file

@ -170,6 +170,9 @@
<ClInclude Include="snes_ntsc_impl.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Equalizer.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
@ -292,5 +295,8 @@
<ClCompile Include="snes_ntsc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Equalizer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View file

@ -11,6 +11,7 @@
#include "UTF8Util.h"
using std::shared_ptr;
using std::unique_ptr;
using utf8::ifstream;
using utf8::ofstream;
using std::string;

View file

@ -2,6 +2,7 @@
#include "SoundManager.h"
#include "../Core/SoundMixer.h"
#include "../Core/Console.h"
#include "../Core/EmuSettings.h"
#include "../Core/MessageManager.h"
SoundManager::SoundManager(shared_ptr<Console> console, HWND hwnd)
@ -61,13 +62,16 @@ string SoundManager::GetAvailableDevices()
void SoundManager::SetAudioDevice(string deviceName)
{
for(SoundDeviceInfo device : GetAvailableDeviceInfo()) {
if(device.description.compare(deviceName) == 0) {
if(memcmp(&_audioDeviceID, &device.guid, 16) != 0) {
memcpy(&_audioDeviceID, &device.guid, 16);
_needReset = true;
if(_audioDeviceName != deviceName) {
for(SoundDeviceInfo device : GetAvailableDeviceInfo()) {
if(device.description.compare(deviceName) == 0) {
_audioDeviceName = deviceName;
if(memcmp(&_audioDeviceID, &device.guid, 16) != 0) {
memcpy(&_audioDeviceID, &device.guid, 16);
_needReset = true;
}
break;
}
break;
}
}
}
@ -126,8 +130,7 @@ bool SoundManager::InitializeDirectSound(uint32_t sampleRate, bool isStereo)
return false;
}
//TODO
int32_t latency = 100; //_console->GetSettings()->GetAudioLatency()
int32_t latency = _console->GetSettings()->GetAudioConfig().AudioLatency;
int32_t requestedByteLatency = (int32_t)((float)(sampleRate * latency) / 1000.0f * waveFormat.nBlockAlign);
_bufferSize = (int32_t)std::ceil((double)requestedByteLatency * 2 / 0x10000) * 0x10000;
@ -266,8 +269,7 @@ void SoundManager::ProcessEndOfFrame()
_secondaryBuffer->GetCurrentPosition(&currentPlayCursor, &safeWriteCursor);
ValidateWriteCursor(safeWriteCursor);
//TODO
uint32_t emulationSpeed = 100; // _console->GetSettings()->GetEmulationSpeed();
uint32_t emulationSpeed = _console->GetSettings()->GetEmulationSpeed();
uint32_t targetRate = _sampleRate;
if(emulationSpeed > 0 && emulationSpeed < 100) {
//Slow down playback when playing at less than 100%
@ -277,9 +279,10 @@ void SoundManager::ProcessEndOfFrame()
ProcessLatency(currentPlayCursor, _lastWriteOffset);
//TODO
uint32_t latency = 100; //_console->GetSettings()->GetAudioLatency();
if(_averageLatency > 0 && emulationSpeed <= 100 && emulationSpeed > 0 && std::abs(_averageLatency - latency) > 50) {
AudioConfig cfg = _console->GetSettings()->GetAudioConfig();
SetAudioDevice(cfg.AudioDevice);
if(_averageLatency > 0 && emulationSpeed <= 100 && emulationSpeed > 0 && std::abs(_averageLatency - cfg.AudioLatency) > 50) {
//Latency is way off (over 50ms gap), stop audio & start again
Stop();
}
@ -288,8 +291,7 @@ void SoundManager::ProcessEndOfFrame()
void SoundManager::PlayBuffer(int16_t *soundBuffer, uint32_t sampleCount, uint32_t sampleRate, bool isStereo)
{
uint32_t bytesPerSample = 2 * (isStereo ? 2 : 1);
//TODO
uint32_t latency = 100; //_console->GetSettings()->GetAudioLatency();
uint32_t latency = _console->GetSettings()->GetAudioConfig().AudioLatency;
if(_sampleRate != sampleRate || _isStereo != isStereo || _needReset || latency != _previousLatency) {
_previousLatency = latency;
Release();

View file

@ -40,7 +40,8 @@ private:
HWND _hWnd;
GUID _audioDeviceID;
bool _needReset = false;
string _audioDeviceName = "";
DWORD _lastWriteOffset = 0;
uint32_t _previousLatency = 0;
bool _playing = false;