Skip to content

Commit

Permalink
PCE: Fixed PSG channels in DDA mode not immediately updating output w…
Browse files Browse the repository at this point in the history
…hen a new output value was written
  • Loading branch information
SourMesen committed Dec 16, 2024
1 parent 86cac32 commit f7c1beb
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 19 deletions.
40 changes: 25 additions & 15 deletions Core/PCE/PcePsg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ void PcePsg::Write(uint16_t addr, uint8_t value)
case 8: _state.LfoFrequency = value; break;
case 9: _state.LfoControl = value; break;
}

UpdateOutput(_emu->GetSettings()->GetPcEngineConfig());
}

void PcePsg::Run()
Expand All @@ -105,27 +107,14 @@ void PcePsg::Run()
}
}

int16_t leftOutput = 0;
int16_t rightOutput = 0;
for(int i = 0; i < 6; i++) {
PcePsgChannel& ch = _channels[i];
ch.Run(minTimer);
leftOutput += (int32_t)ch.GetOutput(true, _state.LeftVolume) * (int32_t)cfg.ChannelVol[i] / 100;
rightOutput += (int32_t)ch.GetOutput(false, _state.RightVolume) * (int32_t)cfg.ChannelVol[i] / 100;
_channels[i].Run(minTimer);
}

_clockCounter += minTimer;
clocksToRun -= minTimer * 6;

if(_prevLeftOutput != leftOutput) {
blip_add_delta(_leftChannel, _clockCounter, leftOutput - _prevLeftOutput);
_prevLeftOutput = leftOutput;
}

if(_prevRightOutput != rightOutput) {
blip_add_delta(_rightChannel, _clockCounter, rightOutput - _prevRightOutput);
_prevRightOutput = rightOutput;
}
UpdateOutput(cfg);
}

if(_clockCounter >= 20000) {
Expand All @@ -135,6 +124,27 @@ void PcePsg::Run()
_lastClock = clock - clocksToRun;
}

void PcePsg::UpdateOutput(PcEngineConfig& cfg)
{
int16_t leftOutput = 0;
int16_t rightOutput = 0;
for(int i = 0; i < 6; i++) {
PcePsgChannel& ch = _channels[i];
leftOutput += (int32_t)ch.GetOutput(true, _state.LeftVolume) * (int32_t)cfg.ChannelVol[i] / 100;
rightOutput += (int32_t)ch.GetOutput(false, _state.RightVolume) * (int32_t)cfg.ChannelVol[i] / 100;
}

if(_prevLeftOutput != leftOutput) {
blip_add_delta(_leftChannel, _clockCounter, leftOutput - _prevLeftOutput);
_prevLeftOutput = leftOutput;
}

if(_prevRightOutput != rightOutput) {
blip_add_delta(_rightChannel, _clockCounter, rightOutput - _prevRightOutput);
_prevRightOutput = rightOutput;
}
}

void PcePsg::UpdateSoundOffset()
{
uint8_t offset = _emu->GetSettings()->GetPcEngineConfig().UseHuC6280aAudio ? 0x10 : 0;
Expand Down
2 changes: 2 additions & 0 deletions Core/PCE/PcePsg.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
class Emulator;
class PceConsole;
class SoundMixer;
struct PcEngineConfig;
struct blip_t;

class PcePsg final : public ISerializable
Expand All @@ -32,6 +33,7 @@ class PcePsg final : public ISerializable

uint32_t _clockCounter = 0;

void UpdateOutput(PcEngineConfig& cfg);
void UpdateSoundOffset();

public:
Expand Down
16 changes: 12 additions & 4 deletions Core/PCE/PcePsgChannel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,15 @@ void PcePsgChannel::Write(uint16_t addr, uint8_t value)

_state.DdaEnabled = (value & 0x40) != 0;
_state.Amplitude = (value & 0x1F);

if(!_state.Enabled && _state.DdaEnabled) {
_state.WriteAddr = 0;

if(_state.DdaEnabled) {
if(_state.Enabled) {
//Update channel output immediately when DDA is enabled
_state.CurrentOutput = (int8_t)_state.DdaOutputValue - _outputOffset;
} else {
_state.WriteAddr = 0;
}
}

break;

case 5:
Expand All @@ -149,6 +153,10 @@ void PcePsgChannel::Write(uint16_t addr, uint8_t value)
case 6:
if(_state.DdaEnabled) {
_state.DdaOutputValue = value & 0x1F;
if(_state.Enabled) {
//Update channel output immediately with the new value when DDA is enabled
_state.CurrentOutput = (int8_t)_state.DdaOutputValue - _outputOffset;
}
} else if(!_state.Enabled) {
_state.WaveData[_state.WriteAddr] = value & 0x1F;
_state.WriteAddr = (_state.WriteAddr + 1) & 0x1F;
Expand Down

0 comments on commit f7c1beb

Please sign in to comment.