swan: Implement headphone/internal speaker output toggle

This commit is contained in:
Adrian Siekierka 2025-03-08 19:52:37 +01:00 committed by tildearrow
parent 03b87258c8
commit b59fc1e8f5
4 changed files with 30 additions and 9 deletions

View file

@ -127,7 +127,9 @@ 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++) {
if (snd->ch_ctrl & (1 << ch)) {
snd->period_counter[ch] += cycles;
uint32_t step = 2048 - snd->frequency[ch];
while (snd->period_counter[ch] >= step) {
@ -135,6 +137,7 @@ static void swan_sound_subtick(swan_sound_t *snd, uint32_t cycles) {
snd->period_counter[ch] -= step;
}
}
}
if (snd->ch_ctrl & SND_CH3_SWEEP) {
snd->sweep_counter += cycles;

View file

@ -107,8 +107,12 @@ void DivPlatformSwan::acquire(short** buf, size_t len) {
}
}
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);
}

View file

@ -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;

View file

@ -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: