Added EPSG audio to both suncore and MMC3

This commit is contained in:
lapinozz 2021-01-03 23:41:07 -05:00 committed by Perkka2
parent 70f1a1b600
commit 5d00c055e6
19 changed files with 2192 additions and 156 deletions

View file

@ -558,6 +558,7 @@
<ClInclude Include="DummyCpu.h" />
<ClInclude Include="Eeprom24C01.h" />
<ClInclude Include="Eeprom24C02.h" />
<ClInclude Include="EPSGAudio.h" />
<ClInclude Include="EventManager.h" />
<ClInclude Include="FaridSlrom.h" />
<ClInclude Include="FaridUnrom.h" />
@ -982,6 +983,7 @@
<ClInclude Include="Waixing178.h" />
<ClInclude Include="Waixing252.h" />
<ClInclude Include="WaveRecorder.h" />
<ClInclude Include="ym3438.h" />
<ClInclude Include="Yoko.h" />
<ClInclude Include="Zapper.h" />
<ClInclude Include="PgoUtilities.h" />
@ -1098,6 +1100,7 @@
<ClCompile Include="VsControlManager.cpp" />
<ClCompile Include="ScaleFilter.cpp" />
<ClCompile Include="WaveRecorder.cpp" />
<ClCompile Include="ym3438.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View file

@ -116,6 +116,9 @@
<Filter Include="Nes\MemoryManager">
<UniqueIdentifier>{13af8497-e820-43f1-9888-85797a29b551}</UniqueIdentifier>
</Filter>
<Filter Include="Nes\Mappers\EPSG">
<UniqueIdentifier>{c9c48ea8-7684-4959-9266-c0b4f0f86956}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="IAudioDevice.h">
@ -1502,6 +1505,12 @@
<ClInclude Include="VbController.h">
<Filter>Nes\Input\Controllers</Filter>
</ClInclude>
<ClInclude Include="ym3438.h">
<Filter>Nes\Mappers\EPSG</Filter>
</ClInclude>
<ClInclude Include="EPSGAudio.h">
<Filter>Nes\Mappers\EPSG</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
@ -1804,5 +1813,8 @@
<ClCompile Include="StudyBoxLoader.cpp">
<Filter>Misc</Filter>
</ClCompile>
<ClCompile Include="ym3438.cpp">
<Filter>Nes\Mappers\EPSG</Filter>
</ClCompile>
</ItemGroup>
</Project>

163
Core/EPSGAudio.h Normal file
View file

@ -0,0 +1,163 @@
#pragma once
#include "stdafx.h"
#include "Snapshotable.h"
#include "APU.h"
#include "BaseExpansionAudio.h"
#include "SSGAudio.h"
#include "Console.h"
#include <array>
#include "ym3438.h"
using EPSGSSGAudio = SSGAudio<AudioChannel::EPSG_L, AudioChannel::EPSG_R>;
class EPSGAudio : public EPSGSSGAudio
{
private:
ym3438_t _chip;
int16_t _lastOutputs[2];
int16_t _currentOutputs[2];
double _clock;
static constexpr uint8_t cycleCount = 24;
struct InputEntry
{
uint8_t addr = 0;
uint8_t data = 0;
uint8_t cycle = 0;
uint8_t wrote = 0;
};
static constexpr uint8_t INPUT_BUFFER_SIZE = cycleCount;
using InputBuffer = std::array<InputEntry, INPUT_BUFFER_SIZE>;
InputBuffer _inputBuffer;
void UpdateOutputLevel()
{
int16_t summedOutput = 0;
for (size_t x = 0; x < 2; x++)
{
_console->GetApu()->AddExpansionAudioDelta(x == 0 ? AudioChannel::EPSG_L : AudioChannel::EPSG_R, _currentOutputs[x] - _lastOutputs[x]);
_lastOutputs[x] = _currentOutputs[x];
}
}
uint8_t GetCurrentCycle() const
{
return static_cast<uint8_t>(std::floor(_clock)) % cycleCount;
}
void WriteToChip(uint8_t a, uint8_t d)
{
const auto cycle = GetCurrentCycle();
if (_inputBuffer[cycle].wrote)
{
std::cout << "DOUBLE WRITE" << std::endl;
}
_inputBuffer[cycle] = {
a,
d,
cycle,
true
};
}
uint32_t getClockFrequency()
{
return _console->GetSettings()->GetEPSGClockFrequency() / 6;
}
protected:
void StreamState(bool saving) override
{
EPSGSSGAudio::StreamState(saving);
ArrayInfo<int16_t> lastOutputs{ _lastOutputs, 2 };
ArrayInfo<int16_t> currentOutputs{ _currentOutputs, 2 };
ArrayInfo<InputBuffer> inputBuffer{ &_inputBuffer };
ValueInfo<ym3438_t> chip{ &_chip };
ValueInfo<double> clock { &_clock };
Stream(lastOutputs, currentOutputs, inputBuffer, chip, clock);
}
void ClockAudio() override
{
EPSGSSGAudio::ClockAudio();
_clock += getClockFrequency() / (double)_console->GetCpu()->GetClockRate(_console->GetModel());
while (_clock >= cycleCount)
{
for (uint8_t x = 0; x < 2; x++)
{
_currentOutputs[x] = 0;
}
for (uint8_t cycle = 0; cycle < cycleCount; cycle++)
{
_clock--;
int16_t samples[2];
OPN2_Clock(&_chip, samples);
for (uint8_t x = 0; x < 2; x++)
{
_currentOutputs[x] += samples[x];
}
auto& input = _inputBuffer[cycle];
if(input.wrote)
{
input.wrote = false;
OPN2_Write(&_chip, input.addr, input.data);
}
}
for (uint8_t x = 0; x < 2; x++)
{
_currentOutputs[x] *= 11;
}
UpdateOutputLevel();
}
}
public:
EPSGAudio(shared_ptr<Console> console) : EPSGSSGAudio(console)
{
memset(_lastOutputs, 0, sizeof(_lastOutputs));
memset(_currentOutputs, 0, sizeof(_currentOutputs));
_inputBuffer = {};
_clock = 0;
OPN2_Reset(&_chip);
OPN2_SetChipType(ym3438_mode_ym2612 | ym3438_mode_readmode);
//OPN2_SetChipType(0);
}
void WriteRegister(uint16_t addr, uint8_t value)
{
EPSGSSGAudio::WriteRegister(addr, value);
switch(addr) {
case 0xC000:
case 0xE000:
case 0xC002:
case 0xE002:
const uint8_t a0 = (addr & 0xF000) == 0xE000;
const uint8_t a1 = !!(addr & 0xF);
WriteToChip(a0 | (a1 << 1), value);
break;
}
}
};

View file

@ -116,7 +116,9 @@ enum class AudioChannel
VRC6 = 7,
VRC7 = 8,
Namco163 = 9,
Sunsoft5B = 10
Sunsoft5B = 10,
EPSG_L = 11,
EPSG_R = 12,
};
enum class EqualizerFilterType
@ -657,8 +659,9 @@ private:
bool _audioSettingsChanged = false;
uint32_t _audioLatency = 50;
double _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 _channelPanning[11] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
uint32_t _EPSGClockFrequency = 3579545;
double _channelVolume[13] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
double _channelPanning[13] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 2.0 };
EqualizerFilterType _equalizerFilterType = EqualizerFilterType::None;
vector<double> _bandGains = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
vector<double> _bands = { { 40,56,80,113,160,225,320,450,600,750,1000,2000,3000,4000,5000,6000,7000,10000,12500,15000 } };
@ -987,6 +990,12 @@ public:
_audioSettingsChanged = true;
}
void SetEPSGClockFrequency(uint32_t clockFrequency)
{
_EPSGClockFrequency = clockFrequency;
_audioSettingsChanged = true;
}
void SetAudioFilterSettings(AudioFilterSettings settings)
{
_audioFilterSettings = settings;
@ -1158,6 +1167,11 @@ public:
return _audioLatency;
}
uint32_t GetEPSGClockFrequency()
{
return _EPSGClockFrequency;
}
void SetVideoFilterType(VideoFilterType videoFilterType)
{
_videoFilterType = videoFilterType;

View file

@ -5,9 +5,29 @@
#include "CPU.h"
#include "EmulationSettings.h"
#include "A12Watcher.h"
#include "EPSGAudio.h"
#include "Sunsoft5bAudio.h"
#ifndef MMC3_DEFAULT_AUDIO
#define MMC3_USE_EPSG
#endif
#ifdef MMC3_USE_EPSG
using AudioClass = EPSGAudio;
#else
using AudioClass = Sunsoft5bAudio;
#endif
class MMC3 : public BaseMapper
{
public:
unique_ptr<AudioClass> _audio;
void ProcessCpuClock() override
{
_audio->Clock();
}
private:
enum class MMC3Registers
{
@ -188,9 +208,10 @@ class MMC3 : public BaseMapper
BaseMapper::StreamState(saving);
ArrayInfo<uint8_t> registers = { _registers, 8 };
SnapshotInfo a12Watcher{ &_a12Watcher };
SnapshotInfo audio{ _audio.get() };
Stream(_state.Reg8000, _state.RegA000, _state.RegA001, _currentRegister, _chrMode, _prgMode,
_irqReloadValue, _irqCounter, _irqReload, _irqEnabled, a12Watcher,
_wramEnabled, _wramWriteProtected, registers);
_wramEnabled, _wramWriteProtected, registers, audio);
}
virtual uint16_t GetPRGPageSize() override { return 0x2000; }
@ -200,6 +221,8 @@ class MMC3 : public BaseMapper
virtual void InitMapper() override
{
_audio.reset(new AudioClass(_console));
//Force MMC3A irqs for boards that are known to use the A revision.
//Some MMC3B boards also have the A behavior, but currently no way to tell them apart.
_forceMmc3RevAIrqs = _romInfo.DatabaseInfo.Chip.substr(0, 5).compare("MMC3A") == 0;
@ -255,6 +278,13 @@ class MMC3 : public BaseMapper
_irqEnabled = true;
break;
}
switch (addr & 0xE000) {
case 0xC000:
case 0xE000:
_audio->WriteRegister(addr, value);
break;
}
}
virtual void TriggerIrq()

135
Core/SSGAudio.h Normal file
View file

@ -0,0 +1,135 @@
#pragma once
#include "stdafx.h"
#include "Snapshotable.h"
#include "APU.h"
#include "BaseExpansionAudio.h"
#include "Console.h"
template<AudioChannel...channels>
class SSGAudio : public BaseExpansionAudio
{
private:
uint8_t _volumeLut[0x10];
uint8_t _currentRegister;
uint8_t _registers[0x10];
int16_t _lastOutput;
int16_t _timer[3];
uint8_t _toneStep[3];
bool _processTick;
uint16_t GetPeriod(int channel)
{
return _registers[channel * 2] | (_registers[channel * 2 + 1] << 8);
}
uint16_t GetEnvelopePeriod()
{
return _registers[0x0B] | (_registers[0x0C] << 8);
}
uint8_t GetNoisePeriod()
{
return _registers[6];
}
uint8_t GetVolume(int channel)
{
return _volumeLut[_registers[8 + channel] & 0x0F];
}
bool IsEnvelopeEnabled(int channel)
{
return (_registers[8 + channel] & 0x10) == 0x10;
}
bool IsToneEnabled(int channel)
{
return ((_registers[7] >> channel) & 0x01) == 0x00;
}
bool IsNoiseEnabled(int channel)
{
return ((_registers[7] >> (channel + 3)) & 0x01) == 0x00;
}
void UpdateChannel(int channel)
{
_timer[channel]--;
if(_timer[channel] <= 0) {
_timer[channel] = GetPeriod(channel);
_toneStep[channel] = (_toneStep[channel] + 1) & 0x0F;
}
}
void UpdateOutputLevel()
{
int16_t summedOutput = 0;
for(int i = 0; i < 3; i++) {
if(IsToneEnabled(i) && _toneStep[i] < 0x08) {
summedOutput += GetVolume(i);
}
}
const auto delta = (summedOutput - _lastOutput) * 15;
(_console->GetApu()->AddExpansionAudioDelta(channels, summedOutput - _lastOutput), ...);
_lastOutput = summedOutput;
}
protected:
void StreamState(bool saving) override
{
BaseExpansionAudio::StreamState(saving);
ArrayInfo<int16_t> timer{ _timer, 3 };
ArrayInfo<uint8_t> registers{ _registers, 0x10 };
ArrayInfo<uint8_t> toneStep{ _toneStep, 3 };
Stream(timer, registers, toneStep, _currentRegister, _lastOutput, _processTick);
}
void ClockAudio() override
{
if(_processTick) {
for(int i = 0; i < 3; i++) {
UpdateChannel(i);
}
UpdateOutputLevel();
}
_processTick = !_processTick;
}
public:
SSGAudio(shared_ptr<Console> console) : BaseExpansionAudio(console)
{
memset(_timer, 0, sizeof(_timer));
memset(_registers, 0, sizeof(_registers));
memset(_toneStep, 0, sizeof(_toneStep));
_currentRegister = 0;
_lastOutput = 0;
_processTick = false;
double output = 1.0;
_volumeLut[0] = 0;
for(int i = 1; i < 0x10; i++) {
//+1.5 dB 2x for every 1 step in volume
output *= 1.1885022274370184377301224648922;
output *= 1.1885022274370184377301224648922;
_volumeLut[i] = (uint8_t)output;
}
}
void WriteRegister(uint16_t addr, uint8_t value)
{
switch(addr) {
case 0xC000:
_currentRegister = value;
break;
case 0xE000:
if(_currentRegister <= 0xF)
_registers[_currentRegister] = value;
break;
}
}
};

View file

@ -264,9 +264,12 @@ int16_t SoundMixer::GetOutputVolume(bool forRightChannel)
GetChannelOutput(AudioChannel::FDS, forRightChannel) * 20 +
GetChannelOutput(AudioChannel::MMC5, forRightChannel) * 43 +
GetChannelOutput(AudioChannel::Namco163, forRightChannel) * 20 +
GetChannelOutput(AudioChannel::Sunsoft5B, forRightChannel) * 15 +
GetChannelOutput(AudioChannel::Sunsoft5B, forRightChannel) +
GetChannelOutput(AudioChannel::VRC6, forRightChannel) * 75 +
GetChannelOutput(AudioChannel::VRC7, forRightChannel));
GetChannelOutput(AudioChannel::VRC7, forRightChannel) +
GetChannelOutput(AudioChannel::EPSG_L, forRightChannel) +
GetChannelOutput(AudioChannel::EPSG_R, forRightChannel)
);
}
void SoundMixer::AddDelta(AudioChannel channel, uint32_t time, int16_t delta)

View file

@ -30,7 +30,7 @@ public:
private:
static constexpr uint32_t MaxSampleRate = 96000;
static constexpr uint32_t MaxSamplesPerFrame = MaxSampleRate / 60 * 4 * 2; //x4 to allow CPU overclocking up to 10x, x2 for panning stereo
static constexpr uint32_t MaxChannelCount = 11;
static constexpr uint32_t MaxChannelCount = 13;
IAudioDevice* _audioDevice;
EmulationSettings* _settings;

View file

@ -2,130 +2,7 @@
#include "stdafx.h"
#include "Snapshotable.h"
#include "APU.h"
#include "BaseExpansionAudio.h"
#include "SSGAudio.h"
#include "Console.h"
class Sunsoft5bAudio : public BaseExpansionAudio
{
private:
uint8_t _volumeLut[0x10];
uint8_t _currentRegister;
uint8_t _registers[0x10];
int16_t _lastOutput;
int16_t _timer[3];
uint8_t _toneStep[3];
bool _processTick;
uint16_t GetPeriod(int channel)
{
return _registers[channel * 2] | (_registers[channel * 2 + 1] << 8);
}
uint16_t GetEnvelopePeriod()
{
return _registers[0x0B] | (_registers[0x0C] << 8);
}
uint8_t GetNoisePeriod()
{
return _registers[6];
}
uint8_t GetVolume(int channel)
{
return _volumeLut[_registers[8 + channel] & 0x0F];
}
bool IsEnvelopeEnabled(int channel)
{
return (_registers[8 + channel] & 0x10) == 0x10;
}
bool IsToneEnabled(int channel)
{
return ((_registers[7] >> channel) & 0x01) == 0x00;
}
bool IsNoiseEnabled(int channel)
{
return ((_registers[7] >> (channel + 3)) & 0x01) == 0x00;
}
void UpdateChannel(int channel)
{
_timer[channel]--;
if(_timer[channel] <= 0) {
_timer[channel] = GetPeriod(channel);
_toneStep[channel] = (_toneStep[channel] + 1) & 0x0F;
}
}
void UpdateOutputLevel()
{
int16_t summedOutput = 0;
for(int i = 0; i < 3; i++) {
if(IsToneEnabled(i) && _toneStep[i] < 0x08) {
summedOutput += GetVolume(i);
}
}
_console->GetApu()->AddExpansionAudioDelta(AudioChannel::Sunsoft5B, summedOutput - _lastOutput);
_lastOutput = summedOutput;
}
protected:
void StreamState(bool saving) override
{
BaseExpansionAudio::StreamState(saving);
ArrayInfo<int16_t> timer{ _timer, 3 };
ArrayInfo<uint8_t> registers{ _registers, 0x10 };
ArrayInfo<uint8_t> toneStep{ _toneStep, 3 };
Stream(timer, registers, toneStep, _currentRegister, _lastOutput, _processTick);
}
void ClockAudio() override
{
if(_processTick) {
for(int i = 0; i < 3; i++) {
UpdateChannel(i);
}
UpdateOutputLevel();
}
_processTick = !_processTick;
}
public:
Sunsoft5bAudio(shared_ptr<Console> console) : BaseExpansionAudio(console)
{
memset(_timer, 0, sizeof(_timer));
memset(_registers, 0, sizeof(_registers));
memset(_toneStep, 0, sizeof(_toneStep));
_currentRegister = 0;
_lastOutput = 0;
_processTick = false;
double output = 1.0;
_volumeLut[0] = 0;
for(int i = 1; i < 0x10; i++) {
//+1.5 dB 2x for every 1 step in volume
output *= 1.1885022274370184377301224648922;
output *= 1.1885022274370184377301224648922;
_volumeLut[i] = (uint8_t)output;
}
}
void WriteRegister(uint16_t addr, uint8_t value)
{
switch(addr & 0xE000) {
case 0xC000:
_currentRegister = value & 0x0F;
break;
case 0xE000:
_registers[_currentRegister] = value;
break;
}
}
};
using Sunsoft5bAudio = SSGAudio<AudioChannel::Sunsoft5B>;

View file

@ -3,11 +3,22 @@
#include "BaseMapper.h"
#include "CPU.h"
#include "Sunsoft5bAudio.h"
#include "EPSGAudio.h"
#ifndef SUNSOFT_DEFAULT_AUDIO
#define SUNSOFT_USE_EPSG
#endif
#ifdef SUNSOFT_USE_EPSG
using AudioClass = EPSGAudio;
#else
using AudioClass = Sunsoft5bAudio;
#endif
class SunsoftFme7 : public BaseMapper
{
private:
unique_ptr<Sunsoft5bAudio> _audio;
unique_ptr<AudioClass> _audio;
uint8_t _command;
uint8_t _workRamValue;
bool _irqEnabled;
@ -24,7 +35,7 @@ protected:
void InitMapper() override
{
_audio.reset(new Sunsoft5bAudio(_console));
_audio.reset(new AudioClass(_console));
_command = 0;
_workRamValue = 0;

1429
Core/ym3438.cpp Normal file

File diff suppressed because it is too large Load diff

211
Core/ym3438.h Normal file
View file

@ -0,0 +1,211 @@
/*
* Copyright (C) 2017-2018 Alexey Khokholov (Nuke.YKT)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
* Nuked OPN2(Yamaha YM3438) emulator.
* Thanks:
* Silicon Pr0n:
* Yamaha YM3438 decap and die shot(digshadow).
* OPLx decapsulated(Matthew Gambrell, Olli Niemitalo):
* OPL2 ROMs.
*
* version: 1.0.9
*/
#ifndef YM3438_H
#define YM3438_H
#ifdef __cplusplus
extern "C" {
#endif
enum {
ym3438_mode_ym2612 = 0x01, /* Enables YM2612 emulation (MD1, MD2 VA2) */
ym3438_mode_readmode = 0x02 /* Enables status read on any port (TeraDrive, MD1 VA7, MD2, etc) */
};
#include <stdint.h>
typedef uintptr_t Bitu;
typedef intptr_t Bits;
typedef uint64_t Bit64u;
typedef int64_t Bit64s;
typedef uint32_t Bit32u;
typedef int32_t Bit32s;
typedef uint16_t Bit16u;
typedef int16_t Bit16s;
typedef uint8_t Bit8u;
typedef int8_t Bit8s;
typedef struct
{
Bit32u cycles;
Bit32u channel;
Bit16s mol, mor;
/* IO */
Bit16u write_data;
Bit8u write_a;
Bit8u write_d;
Bit8u write_a_en;
Bit8u write_d_en;
Bit8u write_busy;
Bit8u write_busy_cnt;
Bit8u write_fm_address;
Bit8u write_fm_data;
Bit16u write_fm_mode_a;
Bit16u address;
Bit8u data;
Bit8u pin_test_in;
Bit8u pin_irq;
Bit8u busy;
/* LFO */
Bit8u lfo_en;
Bit8u lfo_freq;
Bit8u lfo_pm;
Bit8u lfo_am;
Bit8u lfo_cnt;
Bit8u lfo_inc;
Bit8u lfo_quotient;
/* Phase generator */
Bit16u pg_fnum;
Bit8u pg_block;
Bit8u pg_kcode;
Bit32u pg_inc[24];
Bit32u pg_phase[24];
Bit8u pg_reset[24];
Bit32u pg_read;
/* Envelope generator */
Bit8u eg_cycle;
Bit8u eg_cycle_stop;
Bit8u eg_shift;
Bit8u eg_shift_lock;
Bit8u eg_timer_low_lock;
Bit16u eg_timer;
Bit8u eg_timer_inc;
Bit16u eg_quotient;
Bit8u eg_custom_timer;
Bit8u eg_rate;
Bit8u eg_ksv;
Bit8u eg_inc;
Bit8u eg_ratemax;
Bit8u eg_sl[2];
Bit8u eg_lfo_am;
Bit8u eg_tl[2];
Bit8u eg_state[24];
Bit16u eg_level[24];
Bit16u eg_out[24];
Bit8u eg_kon[24];
Bit8u eg_kon_csm[24];
Bit8u eg_kon_latch[24];
Bit8u eg_csm_mode[24];
Bit8u eg_ssg_enable[24];
Bit8u eg_ssg_pgrst_latch[24];
Bit8u eg_ssg_repeat_latch[24];
Bit8u eg_ssg_hold_up_latch[24];
Bit8u eg_ssg_dir[24];
Bit8u eg_ssg_inv[24];
Bit32u eg_read[2];
Bit8u eg_read_inc;
/* FM */
Bit16s fm_op1[6][2];
Bit16s fm_op2[6];
Bit16s fm_out[24];
Bit16u fm_mod[24];
/* Channel */
Bit16s ch_acc[6];
Bit16s ch_out[6];
Bit16s ch_lock;
Bit8u ch_lock_l;
Bit8u ch_lock_r;
Bit16s ch_read;
/* Timer */
Bit16u timer_a_cnt;
Bit16u timer_a_reg;
Bit8u timer_a_load_lock;
Bit8u timer_a_load;
Bit8u timer_a_enable;
Bit8u timer_a_reset;
Bit8u timer_a_load_latch;
Bit8u timer_a_overflow_flag;
Bit8u timer_a_overflow;
Bit16u timer_b_cnt;
Bit8u timer_b_subcnt;
Bit16u timer_b_reg;
Bit8u timer_b_load_lock;
Bit8u timer_b_load;
Bit8u timer_b_enable;
Bit8u timer_b_reset;
Bit8u timer_b_load_latch;
Bit8u timer_b_overflow_flag;
Bit8u timer_b_overflow;
/* Register set */
Bit8u mode_test_21[8];
Bit8u mode_test_2c[8];
Bit8u mode_ch3;
Bit8u mode_kon_channel;
Bit8u mode_kon_operator[4];
Bit8u mode_kon[24];
Bit8u mode_csm;
Bit8u mode_kon_csm;
Bit8u dacen;
Bit16s dacdata;
Bit8u ks[24];
Bit8u ar[24];
Bit8u sr[24];
Bit8u dt[24];
Bit8u multi[24];
Bit8u sl[24];
Bit8u rr[24];
Bit8u dr[24];
Bit8u am[24];
Bit8u tl[24];
Bit8u ssg_eg[24];
Bit16u fnum[6];
Bit8u block[6];
Bit8u kcode[6];
Bit16u fnum_3ch[6];
Bit8u block_3ch[6];
Bit8u kcode_3ch[6];
Bit8u reg_a4;
Bit8u reg_ac;
Bit8u connect[6];
Bit8u fb[6];
Bit8u pan_l[6], pan_r[6];
Bit8u ams[6];
Bit8u pms[6];
Bit8u status;
Bit32u status_time;
} ym3438_t;
void OPN2_Reset(ym3438_t *chip);
void OPN2_SetChipType(Bit32u type);
void OPN2_Clock(ym3438_t *chip, Bit16s *buffer);
void OPN2_Write(ym3438_t *chip, Bit32u port, Bit8u data);
void OPN2_SetTestPin(ym3438_t *chip, Bit32u value);
Bit32u OPN2_ReadTestPin(ym3438_t *chip);
Bit32u OPN2_ReadIRQPin(ym3438_t *chip);
Bit8u OPN2_Read(ym3438_t *chip, Bit32u port);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -23,6 +23,10 @@ namespace Mesen.GUI.Config
[MinMax(0, 100)] public UInt32 Vrc7Volume = 100;
[MinMax(0, 100)] public UInt32 Namco163Volume = 100;
[MinMax(0, 100)] public UInt32 Sunsoft5bVolume = 100;
[MinMax(0, 100)] public UInt32 EPSGVolume_L = 100;
[MinMax(0, 100)] public UInt32 EPSGVolume_R = 100;
[MinMax(10000, 32000000)] public UInt32 EPSGClockFrequency = 3579545;
[MinMax(-100, 100)] public Int32 Square1Panning = 0;
[MinMax(-100, 100)] public Int32 Square2Panning = 0;
@ -35,6 +39,8 @@ namespace Mesen.GUI.Config
[MinMax(-100, 100)] public Int32 Vrc7Panning = 0;
[MinMax(-100, 100)] public Int32 Namco163Panning = 0;
[MinMax(-100, 100)] public Int32 Sunsoft5bPanning = 0;
[MinMax(-100, 100)] public Int32 EPSGPanning_L = -100;
[MinMax(-100, 100)] public Int32 EPSGPanning_R = 100;
[ValidValues(11025, 22050, 44100, 48000, 96000)] public UInt32 SampleRate = 48000;
public bool ReduceSoundInBackground = true;
@ -87,7 +93,7 @@ namespace Mesen.GUI.Config
{
}
static private double ConvertVolume(UInt32 volume)
static public double ConvertVolume(UInt32 volume)
{
return ((double)volume / 100d);
}
@ -114,6 +120,8 @@ namespace Mesen.GUI.Config
InteropEmu.SetChannelVolume(AudioChannel.VRC7, ConvertVolume(audioInfo.Vrc7Volume));
InteropEmu.SetChannelVolume(AudioChannel.Namco163, ConvertVolume(audioInfo.Namco163Volume));
InteropEmu.SetChannelVolume(AudioChannel.Sunsoft5B, ConvertVolume(audioInfo.Sunsoft5bVolume));
InteropEmu.SetChannelVolume(AudioChannel.EPSG_L, ConvertVolume(audioInfo.EPSGVolume_L));
InteropEmu.SetChannelVolume(AudioChannel.EPSG_R, ConvertVolume(audioInfo.EPSGVolume_R));
InteropEmu.SetChannelPanning(AudioChannel.Square1, ConvertPanning(audioInfo.Square1Panning));
InteropEmu.SetChannelPanning(AudioChannel.Square2, ConvertPanning(audioInfo.Square2Panning));
@ -126,6 +134,10 @@ namespace Mesen.GUI.Config
InteropEmu.SetChannelPanning(AudioChannel.VRC7, ConvertPanning(audioInfo.Vrc7Panning));
InteropEmu.SetChannelPanning(AudioChannel.Namco163, ConvertPanning(audioInfo.Namco163Panning));
InteropEmu.SetChannelPanning(AudioChannel.Sunsoft5B, ConvertPanning(audioInfo.Sunsoft5bPanning));
InteropEmu.SetChannelPanning(AudioChannel.EPSG_L, ConvertPanning(audioInfo.EPSGPanning_L));
InteropEmu.SetChannelPanning(AudioChannel.EPSG_R, ConvertPanning(audioInfo.EPSGPanning_R));
InteropEmu.SetEPSGClockFrequency(audioInfo.EPSGClockFrequency);
InteropEmu.SetEqualizerFilterType(audioInfo.EnableEqualizer ? audioInfo.EqualizerFilterType : EqualizerFilterType.None);

View file

@ -41,6 +41,7 @@
this.chkVrc7 = new System.Windows.Forms.CheckBox();
this.chkDmc = new System.Windows.Forms.CheckBox();
this.chkSunsoft = new System.Windows.Forms.CheckBox();
this.chkEPSG = new System.Windows.Forms.CheckBox();
this.chkVrc6 = new System.Windows.Forms.CheckBox();
this.grpSquare1 = new System.Windows.Forms.GroupBox();
this.ctrlSquareInfo1 = new Mesen.GUI.Debugger.Controls.ctrlSquareInfo();
@ -118,6 +119,7 @@
this.tableLayoutPanel2.Controls.Add(this.chkVrc7, 2, 1);
this.tableLayoutPanel2.Controls.Add(this.chkDmc, 0, 4);
this.tableLayoutPanel2.Controls.Add(this.chkSunsoft, 1, 3);
this.tableLayoutPanel2.Controls.Add(this.chkEPSG, 1, 4);
this.tableLayoutPanel2.Controls.Add(this.chkVrc6, 2, 0);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 16);
@ -271,6 +273,20 @@
this.chkSunsoft.UseVisualStyleBackColor = true;
this.chkSunsoft.CheckedChanged += new System.EventHandler(this.chkSoundChannel_CheckedChanged);
//
// chkEPSG
//
this.chkEPSG.AutoSize = true;
this.chkEPSG.Checked = true;
this.chkEPSG.CheckState = System.Windows.Forms.CheckState.Checked;
this.chkEPSG.Location = new System.Drawing.Point(99, 80);
this.chkEPSG.Margin = new System.Windows.Forms.Padding(3, 0, 3, 3);
this.chkEPSG.Name = "chkEPSG";
this.chkEPSG.Size = new System.Drawing.Size(78, 17);
this.chkEPSG.TabIndex = 10;
this.chkEPSG.Text = "EPSG";
this.chkEPSG.UseVisualStyleBackColor = true;
this.chkEPSG.CheckedChanged += new System.EventHandler(this.chkSoundChannel_CheckedChanged);
//
// chkVrc6
//
this.chkVrc6.AutoSize = true;
@ -459,5 +475,6 @@
private System.Windows.Forms.CheckBox chkVrc7;
private System.Windows.Forms.CheckBox chkVrc6;
private System.Windows.Forms.CheckBox chkSunsoft;
private System.Windows.Forms.CheckBox chkEPSG;
}
}

View file

@ -55,6 +55,8 @@ namespace Mesen.GUI.Debugger
private void chkSoundChannel_CheckedChanged(object sender, EventArgs e)
{
AudioInfo audioInfo = ConfigManager.Config.AudioInfo;
InteropEmu.SetChannelVolume(AudioChannel.Square1, chkSquare1.Checked ? 1 : 0);
InteropEmu.SetChannelVolume(AudioChannel.Square2, chkSquare2.Checked ? 1 : 0);
InteropEmu.SetChannelVolume(AudioChannel.Triangle, chkTriangle.Checked ? 1 : 0);
@ -66,6 +68,8 @@ namespace Mesen.GUI.Debugger
InteropEmu.SetChannelVolume(AudioChannel.VRC7, chkVrc7.Checked ? 1 : 0);
InteropEmu.SetChannelVolume(AudioChannel.MMC5, chkMmc5.Checked ? 1 : 0);
InteropEmu.SetChannelVolume(AudioChannel.Sunsoft5B, chkSunsoft.Checked ? 1 : 0);
InteropEmu.SetChannelVolume(AudioChannel.EPSG_L, chkEPSG.Checked ? AudioInfo.ConvertVolume(audioInfo.EPSGVolume_L) : 0);
InteropEmu.SetChannelVolume(AudioChannel.EPSG_R, chkEPSG.Checked ? AudioInfo.ConvertVolume(audioInfo.EPSGVolume_R) : 0);
}
}
}

View file

@ -43,6 +43,8 @@ namespace Mesen.GUI.Forms.Config
this.trkVrc7Vol = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkNamco163Vol = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkSunsoft5b = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkEPSGVol_L = new Mesen.GUI.Controls.ctrlTrackbar();
this.trkEPSGVol_R = new Mesen.GUI.Controls.ctrlTrackbar();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.lblVolumeReductionSettings = new System.Windows.Forms.Label();
this.chkEnableAudio = new System.Windows.Forms.CheckBox();
@ -78,6 +80,8 @@ namespace Mesen.GUI.Forms.Config
this.trkVrc7Pan = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.trkNamcoPan = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.trkSunsoftPan = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.trkEPSGPan_L = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.trkEPSGPan_R = new Mesen.GUI.Controls.ctrlHorizontalTrackbar();
this.tpgEqualizer = new System.Windows.Forms.TabPage();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.chkEnableEqualizer = new System.Windows.Forms.CheckBox();
@ -142,6 +146,8 @@ namespace Mesen.GUI.Forms.Config
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.chkDisableDynamicSampleRate = new Mesen.GUI.Controls.ctrlRiskyOption();
this.chkDisableNoiseModeFlag = new Mesen.GUI.Controls.ctrlRiskyOption();
this.nudEPSGClockFrequency = new Mesen.GUI.Controls.MesenNumericUpDown();
this.lblEPSGClockFrequency = new System.Windows.Forms.Label();
this.chkSilenceTriangleHighFreq = new System.Windows.Forms.CheckBox();
this.chkSwapDutyCycles = new Mesen.GUI.Controls.ctrlRiskyOption();
this.chkReduceDmcPopping = new System.Windows.Forms.CheckBox();
@ -196,7 +202,7 @@ namespace Mesen.GUI.Forms.Config
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 6;
this.tableLayoutPanel1.ColumnCount = 7;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
@ -214,7 +220,9 @@ namespace Mesen.GUI.Forms.Config
this.tableLayoutPanel1.Controls.Add(this.trkVrc6Vol, 2, 1);
this.tableLayoutPanel1.Controls.Add(this.trkVrc7Vol, 3, 1);
this.tableLayoutPanel1.Controls.Add(this.trkNamco163Vol, 4, 1);
this.tableLayoutPanel1.Controls.Add(this.trkSunsoft5b, 5, 1);
this.tableLayoutPanel1.Controls.Add(this.trkSunsoft5b, 6, 0);
this.tableLayoutPanel1.Controls.Add(this.trkEPSGVol_L, 5, 1);
this.tableLayoutPanel1.Controls.Add(this.trkEPSGVol_R, 6, 1);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 16);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
@ -405,6 +413,36 @@ namespace Mesen.GUI.Forms.Config
this.trkSunsoft5b.Text = "Sunsoft";
this.trkSunsoft5b.Value = 50;
//
// trkEPSGVol_L
//
this.trkEPSGVol_L.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.trkEPSGVol_L.Location = new System.Drawing.Point(387, 160);
this.trkEPSGVol_L.Margin = new System.Windows.Forms.Padding(0);
this.trkEPSGVol_L.Maximum = 100;
this.trkEPSGVol_L.MaximumSize = new System.Drawing.Size(63, 160);
this.trkEPSGVol_L.Minimum = 0;
this.trkEPSGVol_L.MinimumSize = new System.Drawing.Size(63, 160);
this.trkEPSGVol_L.Name = "trkEPSGVol_L";
this.trkEPSGVol_L.Size = new System.Drawing.Size(63, 160);
this.trkEPSGVol_L.TabIndex = 22;
this.trkEPSGVol_L.Text = "EPSG Left";
this.trkEPSGVol_L.Value = 100;
//
// trkEPSGVol_R
//
this.trkEPSGVol_R.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.trkEPSGVol_R.Location = new System.Drawing.Point(387, 160);
this.trkEPSGVol_R.Margin = new System.Windows.Forms.Padding(0);
this.trkEPSGVol_R.Maximum = 100;
this.trkEPSGVol_R.MaximumSize = new System.Drawing.Size(63, 160);
this.trkEPSGVol_R.Minimum = 0;
this.trkEPSGVol_R.MinimumSize = new System.Drawing.Size(63, 160);
this.trkEPSGVol_R.Name = "trkEPSGVol_R";
this.trkEPSGVol_R.Size = new System.Drawing.Size(63, 160);
this.trkEPSGVol_R.TabIndex = 22;
this.trkEPSGVol_R.Text = "EPSG Right";
this.trkEPSGVol_R.Value = 100;
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 2;
@ -696,7 +734,7 @@ namespace Mesen.GUI.Forms.Config
this.tabMain.Location = new System.Drawing.Point(0, 0);
this.tabMain.Name = "tabMain";
this.tabMain.SelectedIndex = 0;
this.tabMain.Size = new System.Drawing.Size(477, 373);
this.tabMain.Size = new System.Drawing.Size(477, 389);
this.tabMain.TabIndex = 4;
//
// tpgGeneral
@ -727,7 +765,7 @@ namespace Mesen.GUI.Forms.Config
this.tpgPanning.Location = new System.Drawing.Point(4, 22);
this.tpgPanning.Name = "tpgPanning";
this.tpgPanning.Padding = new System.Windows.Forms.Padding(3);
this.tpgPanning.Size = new System.Drawing.Size(469, 347);
this.tpgPanning.Size = new System.Drawing.Size(469, 389);
this.tpgPanning.TabIndex = 4;
this.tpgPanning.Text = "Panning";
this.tpgPanning.UseVisualStyleBackColor = true;
@ -747,11 +785,13 @@ namespace Mesen.GUI.Forms.Config
this.tableLayoutPanel6.Controls.Add(this.trkVrc6Pan, 1, 2);
this.tableLayoutPanel6.Controls.Add(this.trkVrc7Pan, 1, 3);
this.tableLayoutPanel6.Controls.Add(this.trkNamcoPan, 1, 4);
this.tableLayoutPanel6.Controls.Add(this.trkSunsoftPan, 1, 5);
this.tableLayoutPanel6.Controls.Add(this.trkSunsoftPan, 0, 6);
this.tableLayoutPanel6.Controls.Add(this.trkEPSGPan_L, 0, 5);
this.tableLayoutPanel6.Controls.Add(this.trkEPSGPan_R, 1, 5);
this.tableLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel6.Location = new System.Drawing.Point(3, 3);
this.tableLayoutPanel6.Name = "tableLayoutPanel6";
this.tableLayoutPanel6.RowCount = 7;
this.tableLayoutPanel6.RowCount = 8;
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle());
@ -760,7 +800,7 @@ namespace Mesen.GUI.Forms.Config
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel6.Size = new System.Drawing.Size(463, 341);
this.tableLayoutPanel6.Size = new System.Drawing.Size(463, 389);
this.tableLayoutPanel6.TabIndex = 3;
//
// trkSquare1Pan
@ -928,6 +968,36 @@ namespace Mesen.GUI.Forms.Config
this.trkSunsoftPan.Text = "Sunsoft";
this.trkSunsoftPan.Value = 0;
//
// trkEPSGPan_L
//
this.trkEPSGPan_L.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.trkEPSGPan_L.Location = new System.Drawing.Point(244, 275);
this.trkEPSGPan_L.Margin = new System.Windows.Forms.Padding(0);
this.trkEPSGPan_L.Maximum = 100;
this.trkEPSGPan_L.MaximumSize = new System.Drawing.Size(63, 160);
this.trkEPSGPan_L.Minimum = -100;
this.trkEPSGPan_L.MinimumSize = new System.Drawing.Size(206, 55);
this.trkEPSGPan_L.Name = "trkEPSGPan_L";
this.trkEPSGPan_L.Size = new System.Drawing.Size(206, 55);
this.trkEPSGPan_L.TabIndex = 22;
this.trkEPSGPan_L.Text = "EPSG Left";
this.trkEPSGPan_L.Value = -100;
//
// trkEPSGPan_R
//
this.trkEPSGPan_R.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.trkEPSGPan_R.Location = new System.Drawing.Point(244, 275);
this.trkEPSGPan_R.Margin = new System.Windows.Forms.Padding(0);
this.trkEPSGPan_R.Maximum = 100;
this.trkEPSGPan_R.MaximumSize = new System.Drawing.Size(63, 160);
this.trkEPSGPan_R.Minimum = -100;
this.trkEPSGPan_R.MinimumSize = new System.Drawing.Size(206, 55);
this.trkEPSGPan_R.Name = "trkEPSGPan_R";
this.trkEPSGPan_R.Size = new System.Drawing.Size(206, 55);
this.trkEPSGPan_R.TabIndex = 22;
this.trkEPSGPan_R.Text = "EPSG Right";
this.trkEPSGPan_R.Value = 100;
//
// tpgEqualizer
//
this.tpgEqualizer.Controls.Add(this.groupBox1);
@ -1897,13 +1967,16 @@ namespace Mesen.GUI.Forms.Config
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel3.Controls.Add(this.chkDisableDynamicSampleRate, 0, 2);
this.tableLayoutPanel3.Controls.Add(this.chkDisableNoiseModeFlag, 0, 4);
this.tableLayoutPanel3.Controls.Add(this.nudEPSGClockFrequency, 0, 5);
this.tableLayoutPanel3.Controls.Add(this.lblEPSGClockFrequency, 0, 5);
this.tableLayoutPanel3.Controls.Add(this.chkSilenceTriangleHighFreq, 0, 0);
this.tableLayoutPanel3.Controls.Add(this.chkSwapDutyCycles, 0, 3);
this.tableLayoutPanel3.Controls.Add(this.chkReduceDmcPopping, 0, 1);
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel3.Location = new System.Drawing.Point(3, 3);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowCount = 6;
this.tableLayoutPanel3.RowCount = 7;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F));
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F));
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F));
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 24F));
@ -1932,6 +2005,32 @@ namespace Mesen.GUI.Forms.Config
this.chkDisableNoiseModeFlag.Size = new System.Drawing.Size(463, 24);
this.chkDisableNoiseModeFlag.TabIndex = 3;
this.chkDisableNoiseModeFlag.Text = "Disable noise channel mode flag";
//
// nudEPSGClockFrequency
//
this.nudEPSGClockFrequency.Dock = System.Windows.Forms.DockStyle.Fill;
this.nudEPSGClockFrequency.Location = new System.Drawing.Point(0, 96);
this.nudEPSGClockFrequency.Size = new System.Drawing.Size(463, 24);
this.nudEPSGClockFrequency.TabIndex = 3;
this.nudEPSGClockFrequency.Text = "EPSG Clock Frquency";
this.nudEPSGClockFrequency.Name = "nudEPSGClockFrequency";
this.nudEPSGClockFrequency.Increment = new decimal(100000);
this.nudEPSGClockFrequency.Minimum = new decimal(10000);
this.nudEPSGClockFrequency.Maximum = new decimal(32000000);
this.nudEPSGClockFrequency.Value = new decimal(0);
this.nudEPSGClockFrequency.MaximumSize = new System.Drawing.Size(10000, 20);
this.nudEPSGClockFrequency.MinimumSize = new System.Drawing.Size(200, 21);
this.nudEPSGClockFrequency.DecimalPlaces = 0;
//
// lblEPSGClockFrequency
//
this.lblEPSGClockFrequency.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblEPSGClockFrequency.AutoSize = true;
this.lblEPSGClockFrequency.Location = new System.Drawing.Point(163, 6);
this.lblEPSGClockFrequency.Name = "lblEPSGClockFrequency";
this.lblEPSGClockFrequency.Size = new System.Drawing.Size(15, 13);
this.lblEPSGClockFrequency.TabIndex = 3;
this.lblEPSGClockFrequency.Text = "EPSG Clock Frequency (default is 3579545Hz)";
//
// chkSilenceTriangleHighFreq
//
@ -1968,7 +2067,7 @@ namespace Mesen.GUI.Forms.Config
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(477, 402);
this.ClientSize = new System.Drawing.Size(477, 450);
this.Controls.Add(this.tabMain);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
@ -2051,6 +2150,8 @@ namespace Mesen.GUI.Forms.Config
private Controls.ctrlTrackbar trkVrc7Vol;
private Controls.ctrlTrackbar trkNamco163Vol;
private Controls.ctrlTrackbar trkSunsoft5b;
private Controls.ctrlTrackbar trkEPSGVol_L;
private Controls.ctrlTrackbar trkEPSGVol_R;
private System.Windows.Forms.TabControl tabMain;
private System.Windows.Forms.TabPage tpgGeneral;
private System.Windows.Forms.TabPage tpgVolume;
@ -2091,6 +2192,8 @@ namespace Mesen.GUI.Forms.Config
private Controls.ctrlHorizontalTrackbar trkVrc7Pan;
private Controls.ctrlHorizontalTrackbar trkNamcoPan;
private Controls.ctrlHorizontalTrackbar trkSunsoftPan;
private Controls.ctrlHorizontalTrackbar trkEPSGPan_L;
private Controls.ctrlHorizontalTrackbar trkEPSGPan_R;
private Controls.ctrlHorizontalTrackbar trkSquare1Pan;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel5;
private System.Windows.Forms.CheckBox chkCrossFeedEnabled;
@ -2098,6 +2201,8 @@ namespace Mesen.GUI.Forms.Config
private System.Windows.Forms.Label lblCrossFeedRatio;
private Controls.ctrlHorizontalTrackbar trkTrianglePan;
private ctrlRiskyOption chkDisableNoiseModeFlag;
private MesenNumericUpDown nudEPSGClockFrequency;
private System.Windows.Forms.Label lblEPSGClockFrequency;
private System.Windows.Forms.TabPage tpgEqualizer;
private System.Windows.Forms.TableLayoutPanel tlpEqualizer;
private ctrlTrackbar trkBand6Gain;

View file

@ -43,6 +43,8 @@ namespace Mesen.GUI.Forms.Config
AddBinding("Vrc7Volume", trkVrc7Vol);
AddBinding("Namco163Volume", trkNamco163Vol);
AddBinding("Sunsoft5bVolume", trkSunsoft5b);
AddBinding("EPSGVolume_L", trkEPSGVol_L);
AddBinding("EPSGVolume_R", trkEPSGVol_R);
AddBinding("Square1Panning", trkSquare1Pan);
AddBinding("Square2Panning", trkSquare2Pan);
@ -55,6 +57,10 @@ namespace Mesen.GUI.Forms.Config
AddBinding("Vrc7Panning", trkVrc7Pan);
AddBinding("Namco163Panning", trkNamcoPan);
AddBinding("Sunsoft5bPanning", trkSunsoftPan);
AddBinding("EPSGPanning_L", trkEPSGPan_L);
AddBinding("EPSGPanning_R", trkEPSGPan_R);
AddBinding("EPSGClockFrequency", nudEPSGClockFrequency);
AddBinding("AudioLatency", nudLatency);
AddBinding("SampleRate", cboSampleRate);

View file

@ -208,6 +208,7 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void SetBandGain(int band, double gain);
[DllImport(DLLPath)] public static extern void SetSampleRate(UInt32 sampleRate);
[DllImport(DLLPath)] public static extern void SetAudioLatency(UInt32 msLatency);
[DllImport(DLLPath)] public static extern void SetEPSGClockFrequency(UInt32 clockFrequency);
[DllImport(DLLPath)] public static extern void SetAudioFilterSettings(AudioFilterSettings settings);
[DllImport(DLLPath)] public static extern void SetRunAheadFrames(UInt32 frameCount);
@ -2297,7 +2298,9 @@ namespace Mesen.GUI
VRC6 = 7,
VRC7 = 8,
Namco163 = 9,
Sunsoft5B = 10
Sunsoft5B = 10,
EPSG_L = 11,
EPSG_R= 12
}
public enum EqualizerFilterType

View file

@ -633,6 +633,7 @@ namespace InteropEmu {
DllExport void __stdcall SetMasterVolume(double volume, double volumeReduction, ConsoleId consoleId) { GetConsoleById(consoleId)->GetSettings()->SetMasterVolume(volume, volumeReduction); }
DllExport void __stdcall SetSampleRate(uint32_t sampleRate) { _settings->SetSampleRate(sampleRate); }
DllExport void __stdcall SetAudioLatency(uint32_t msLatency) { _settings->SetAudioLatency(msLatency); }
DllExport void __stdcall SetEPSGClockFrequency(uint32_t clockFrequency) { _settings->SetEPSGClockFrequency(clockFrequency); }
DllExport void __stdcall SetAudioFilterSettings(AudioFilterSettings settings) { _settings->SetAudioFilterSettings(settings); }
DllExport void __stdcall SetRunAheadFrames(uint32_t frameCount) { _settings->SetRunAheadFrames(frameCount); }