diff --git a/src/engine/platform/sound/swan.c b/src/engine/platform/sound/swan.c index 5fce1cc6c..838bd69b2 100644 --- a/src/engine/platform/sound/swan.c +++ b/src/engine/platform/sound/swan.c @@ -127,12 +127,15 @@ void swan_sound_out(swan_sound_t *snd, uint16_t port, uint8_t value) { } static void swan_sound_subtick(swan_sound_t *snd, uint32_t cycles) { + // TODO: Do period counters update when a channel is inactive? for (int ch = 0; ch < 4; ch++) { - snd->period_counter[ch] += cycles; - uint32_t step = 2048 - snd->frequency[ch]; - while (snd->period_counter[ch] >= step) { - snd->sample_index[ch] = (snd->sample_index[ch] + 1) & 0x1F; - snd->period_counter[ch] -= step; + if (snd->ch_ctrl & (1 << ch)) { + snd->period_counter[ch] += cycles; + uint32_t step = 2048 - snd->frequency[ch]; + while (snd->period_counter[ch] >= step) { + snd->sample_index[ch] = (snd->sample_index[ch] + 1) & 0x1F; + snd->period_counter[ch] -= step; + } } } diff --git a/src/engine/platform/swan.cpp b/src/engine/platform/swan.cpp index 9a0c2acfc..698afb1bc 100644 --- a/src/engine/platform/swan.cpp +++ b/src/engine/platform/swan.cpp @@ -107,8 +107,12 @@ void DivPlatformSwan::acquire(short** buf, size_t len) { } } - buf[0][h] = ws.output_left; - buf[1][h] = ws.output_right; + if (stereo) { + buf[0][h] = ws.output_left; + buf[1][h] = ws.output_right; + } else { + buf[0][h] = ((int)ws.output_speaker - 0x80) << 8; + } } for (int i=0; i<4; i++) { @@ -597,7 +601,7 @@ void DivPlatformSwan::reset() { } int DivPlatformSwan::getOutputCount() { - return 2; + return stereo?2:1; } void DivPlatformSwan::notifyWaveChange(int wave) { @@ -627,6 +631,7 @@ void DivPlatformSwan::setFlags(const DivConfig& flags) { chipClock=3072000; CHECK_CUSTOM_CLOCK; rate=chipClock/128; + stereo=flags.getBool("stereo",false); for (int i=0; i<4; i++) { oscBuf[i]->setRate(rate); } diff --git a/src/engine/platform/swan.h b/src/engine/platform/swan.h index d4de0f061..31ef96faa 100644 --- a/src/engine/platform/swan.h +++ b/src/engine/platform/swan.h @@ -38,6 +38,7 @@ class DivPlatformSwan: public DivDispatch { Channel chan[4]; DivDispatchOscBuffer* oscBuf[4]; bool isMuted[4]; + bool stereo=true; bool pcm, sweep, furnaceDac, setPos; unsigned char sampleBank, noise; int dacPeriod, dacRate; diff --git a/src/gui/sysConf.cpp b/src/gui/sysConf.cpp index fbea92ddc..60286da16 100644 --- a/src/gui/sysConf.cpp +++ b/src/gui/sysConf.cpp @@ -2664,7 +2664,19 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl } break; } - case DIV_SYSTEM_SWAN: + case DIV_SYSTEM_SWAN: { + bool stereo=flags.getBool("stereo",true); + if (ImGui::Checkbox(_("Headphone output##_SWAN_STEREO"),&stereo)) { + altered=true; + } + + if (altered) { + e->lockSave([&]() { + flags.set("stereo",stereo); + }); + } + break; + } case DIV_SYSTEM_BUBSYS_WSG: case DIV_SYSTEM_PET: case DIV_SYSTEM_GA20: