From 4ebdad0c2dedff9d206e255130d30a2001a707a1 Mon Sep 17 00:00:00 2001 From: Simon Gellis Date: Fri, 15 Aug 2025 00:24:07 -0400 Subject: [PATCH] Add Floogle's latest audio fixes --- core/vsu.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/core/vsu.c b/core/vsu.c index 6d129cd..fe0a668 100644 --- a/core/vsu.c +++ b/core/vsu.c @@ -132,14 +132,19 @@ static void vsuEmulateChannel(VB *sim, Channel *chan) { } /* Envelope modification */ - if (chan->env.enb && !chan->env.modmask && chan->env.clocks == 0) { - if (chan->env.dir == 0 && chan->env.value != 0) - chan->env.value--; - else if (chan->env.dir == 1 && chan->env.value != 15) - chan->env.value++; - else if (chan->env.rep) - chan->env.value = chan->env.reload; - else chan->env.modmask = 1; + if (chan->env.clocks == 0) { + uint8_t new_envelope = chan->env.value; + if (chan->env.dir == 0 && chan->env.value != 0) { + new_envelope--; + } else if (chan->env.dir == 1 && chan->env.value != 15) { + new_envelope++; + } else if (chan->env.rep && chan->env.modmask != 2) { + new_envelope = chan->env.reload; + chan->env.modmask = 0; + } else if (!chan->env.modmask) chan->env.modmask = 1; + if (chan->env.enb && !chan->env.modmask) { + chan->env.value = new_envelope; + } chan->env.clocks = ((uint32_t) chan->env.interval + 1) * 307220; } @@ -215,6 +220,7 @@ static void vsuWriteEV0(VB *sim, int index, uint8_t value) { chan->env.interval = value & 7; chan->env.value = value >> 4 & 15; chan->env.reload = chan->env.value; + if (chan->env.modmask == 1) chan->env.modmask = 2; if (index == 4) { chan->freqmod = vsuCheckFreqMod(sim); vsuNextFreqMod(sim, chan); @@ -231,6 +237,8 @@ static void vsuWriteEV1(VB *sim, int index, uint8_t value) { /* Parse fields */ chan->env.enb = value & 1; chan->env.rep = value >> 1 & 1; + if (!chan->env.rep && ((chan->env.reload == 0 && chan->env.dir == 0) || (chan->env.reload == 15 && chan->env.dir == 1))) + chan->env.modmask = 1; /* Processing by channel */ switch (index) { @@ -286,8 +294,9 @@ static void vsuWriteINT(VB *sim, int index, uint8_t value) { /* Update state */ chan->int_.clocks = 76805 * ((uint32_t) chan->int_.interval + 1); chan->env.modmask = 0; - if (chan->env.enb) - chan->env.clocks = 307220 * ((uint32_t) chan->env.interval + 1); + if (!chan->env.rep && ((chan->env.reload == 0 && chan->env.dir == 0) || (chan->env.reload == 15 && chan->env.dir == 1))) + chan->env.modmask = 1; + chan->env.clocks = 307220 * ((uint32_t) chan->env.interval + 1); if (index != 5) { chan->wave.sample = 0; chan->clocks = 4 * (2048 - (uint32_t) chan->freq.current); @@ -377,7 +386,7 @@ static void vsuEmulate(VB *sim, uint32_t clocks) { /* Clocks until next state change */ chan->until = chan->clocks; - if (chan->env.enb && !chan->env.modmask && + if (chan->env.enb && chan->env.modmask != 2 && chan->env.clocks < chan->until) chan->until = chan->env.clocks; if (chan->int_.auto_ && chan->int_.clocks < chan->until) @@ -387,7 +396,7 @@ static void vsuEmulate(VB *sim, uint32_t clocks) { /* Manage clocks */ chan->clocks -= chan->until; - if (chan->env.enb && !chan->env.modmask) + if (chan->env.enb && chan->env.modmask != 2) chan->env.clocks -= chan->until; if (chan->int_.auto_) chan->int_.clocks -= chan->until;