Replaced S5b emu with emu2149 for better accuracy

including missing features like envelope and noise
This commit is contained in:
Perkka2 2021-08-03 17:23:33 +02:00
parent d06a647428
commit fdee47855a
3 changed files with 400 additions and 310 deletions

View file

@ -4,8 +4,89 @@
#include "APU.h"
#include "BaseExpansionAudio.h"
#include "Console.h"
#include "emu2149.h"
//#define SSG_USE_OLD_EMU
#ifndef SSG_USE_OLD_EMU
#define SSG_USE_EMU2149
#endif
#ifdef SSG_USE_EMU2149
template<AudioChannel...channels>
class SSGAudio : public BaseExpansionAudio
{
private:
std::unique_ptr<PSG, void(*)(PSG*)> _psg;
uint8_t _currentRegister;
int16_t _lastOutput;
int16_t _currentOutput;
double _clock;
bool _processTick;
static constexpr uint8_t cycleCount = 1;
void UpdateOutputLevel()
{
(_console->GetApu()->AddExpansionAudioDelta(channels, _currentOutput - _lastOutput), ...);
_lastOutput = _currentOutput;
}
protected:
void StreamState(bool saving) override
{
BaseExpansionAudio::StreamState(saving);
ValueInfo<PSG> psg{ _psg.get() };
Stream( _currentRegister, _lastOutput, _clock, psg);
}
void ClockAudio() override
{
_clock += GetSSGClockFrequency() / (double)_console->GetCpu()->GetClockRate(_console->GetModel());
while (_clock >= cycleCount)
{
_currentOutput = 0;
for (uint8_t cycle = 0; cycle < cycleCount; cycle++)
{
_clock--;
_currentOutput = PSG_calc(_psg.get());
}
_currentOutput /= 26;
UpdateOutputLevel();
}
}
virtual uint32_t GetSSGClockFrequency()
{
return _console->GetCpu()->GetClockRate(_console->GetModel()) / 2;
}
public:
SSGAudio(shared_ptr<Console> console) : BaseExpansionAudio(console), _psg{ PSG_new(1 , 1), &PSG_delete }
{
_currentRegister = 0;
_lastOutput = 0;
_clock = 0;
PSG_reset(_psg.get());
}
void WriteRegister(uint16_t addr, uint8_t value)
{
switch (addr) {
case 0xC000:
_currentRegister = value;
break;
case 0xE000:
if (_currentRegister <= 0xF)
PSG_writeReg(_psg.get(), _currentRegister, value);
break;
}
}
};
#else
template<AudioChannel...channels>
class SSGAudio : public BaseExpansionAudio
{
@ -143,3 +224,4 @@ public:
}
}
};
#endif

View file

@ -32,10 +32,10 @@ static uint32_t voltbl[2][32] = {
0x0B, 0x0D, 0x0F, 0x12,
0x16, 0x1A, 0x1F, 0x25, 0x2D, 0x35, 0x3F, 0x4C, 0x5A, 0x6A, 0x7F, 0x97,
0xB4, 0xD6, 0xFF, 0xFF},
{0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x05, 0x05, 0x07, 0x07,
0x0B, 0x0B, 0x0F, 0x0F,
0x16, 0x16, 0x1F, 0x1F, 0x2D, 0x2D, 0x3F, 0x3F, 0x5A, 0x5A, 0x7F, 0x7F,
0xB4, 0xB4, 0xFF, 0xFF}
{0x00, 0x00, 0x03, 0x03, 0x04, 0x04, 0x06, 0x06, 0x09, 0x09, 0x0D, 0x0D,
0x12, 0x12, 0x1D, 0x1D,
0x22, 0x22, 0x37, 0x37, 0x4D, 0x4D, 0x62, 0x62, 0x82, 0x82, 0xA6, 0xA6,
0xD0, 0xD0, 0xFF, 0xFF}
};
static uint8_t regmsk[16] = {
@ -52,16 +52,23 @@ internal_refresh (PSG * psg)
{
psg->base_incr = 1 << GETA_BITS;
psg->realstep = (uint32_t)((1 << 31) / psg->rate);
psg->psgstep = (uint32_t) ((1 << 31) / (psg->clk / 16));
psg->psgstep = (uint32_t)((1 << 31) / (psg->clk / 8));
psg->psgtime = 0;
}
else
{
psg->base_incr =
(uint32_t) ((double) psg->clk * (1 << GETA_BITS) / (16 * psg->rate));
(uint32_t)((double)psg->clk * (1 << GETA_BITS) / (8 * psg->rate));
}
}
void
PSG_set_clock(PSG* psg, uint32_t c)
{
psg->clk = c;
internal_refresh(psg);
}
void
PSG_set_rate(PSG* psg, uint32_t r)
{

View file

@ -68,6 +68,7 @@ extern "C"
} PSG;
void PSG_set_quality(PSG* psg, uint32_t q);
void PSG_set_clock(PSG* psg, uint32_t c);
void PSG_set_rate(PSG* psg, uint32_t r);
PSG* PSG_new(uint32_t clk, uint32_t rate);
void PSG_reset(PSG*);