Audio: Added stereo effects + reverb options
This commit is contained in:
parent
5ce8b20fd1
commit
d89cdfab01
25 changed files with 758 additions and 27 deletions
21
Core/BaseSoundFilter.cpp
Normal file
21
Core/BaseSoundFilter.cpp
Normal 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
14
Core/BaseSoundFilter.h
Normal 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();
|
||||
};
|
|
@ -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" />
|
||||
|
|
|
@ -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>
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
31
Core/ReverbFilter.cpp
Normal 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
57
Core/ReverbFilter.h
Normal 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);
|
||||
};
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
35
Core/StereoDelayFilter.cpp
Normal file
35
Core/StereoDelayFilter.cpp
Normal 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
16
Core/StereoDelayFilter.h
Normal 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);
|
||||
};
|
24
Core/StereoPanningFilter.cpp
Normal file
24
Core/StereoPanningFilter.cpp
Normal 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;
|
||||
}
|
16
Core/StereoPanningFilter.h
Normal file
16
Core/StereoPanningFilter.h
Normal 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);
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
339
GUI.NET/Forms/Config/frmAudioConfig.Designer.cs
generated
339
GUI.NET/Forms/Config/frmAudioConfig.Designer.cs
generated
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue