VSU fixes

This commit is contained in:
Guy Perfect 2024-10-20 23:09:58 -05:00
parent a285065102
commit 0a57ef0faf
2 changed files with 36 additions and 40 deletions

View File

@ -509,7 +509,7 @@ VBAPI vbOnRead vbGetReadCallback(VB *sim) {
/* Retrieve the audio samples buffer */ /* Retrieve the audio samples buffer */
VBAPI void* vbGetSamples(VB *sim, uint32_t *capacity, uint32_t *position) { VBAPI void* vbGetSamples(VB *sim, uint32_t *capacity, uint32_t *position) {
if (capacity == NULL) { if (sim->vsu.out.samples == NULL) {
if (capacity != NULL) if (capacity != NULL)
*capacity = 0; *capacity = 0;
if (position != NULL) if (position != NULL)

View File

@ -75,12 +75,13 @@ static void vsuNextFreqMod(VB *sim, Channel *chan) {
/* Process one channel */ /* Process one channel */
static void vsuEmulateChannel(VB *sim, int index, uint32_t clocks) { static void vsuEmulateChannel(VB *sim, int index, uint32_t clocks) {
uint32_t bit; /* Pseudorandom bit */ uint32_t bit; /* Pseudorandom bit */
Channel *chan; /* Channel handle */ Channel *chan; /* Channel handle */
uint32_t level; /* Stereo output level */ int freqmod; /* Frequency modifications enabled */
uint32_t sample; /* Input sample */ uint32_t level; /* Stereo output level */
uint32_t until; /* Clocks to process sub-channel components */ uint32_t sample; /* Input sample */
int e; /* Iterator */ uint32_t until; /* Clocks to process sub-channel components */
int e; /* Iterator */
/* Select channel */ /* Select channel */
chan = &sim->vsu.channels[index]; chan = &sim->vsu.channels[index];
@ -107,39 +108,42 @@ static void vsuEmulateChannel(VB *sim, int index, uint32_t clocks) {
/* Process all clocks */ /* Process all clocks */
do { do {
/* Frequency modifications are active */
freqmod =
index == 4 && /* Channel 5 */
sim->vsu.freqmod.enb && /* Modifications enabled */
sim->vsu.freqmod.interval != 0 /* Modifications valid */
;
/* Clocks until next state change */ /* Clocks until next state change */
until = clocks; until = clocks;
if (chan->clocks < until) /* Next sample */ if (chan->clocks < until)
until = chan->clocks; until = chan->clocks;
if ( if (chan->env.enb && chan->env.clocks < until)
chan->env.enb && /* Modifications enabled */ until = chan->env.clocks;
chan->env.clocks < until /* Next modification */ if (chan->int_.auto_ && chan->int_.clocks < until)
) until = chan->env.clocks; until = chan->int_.clocks;
if ( if (freqmod && sim->vsu.freqmod.clocks < until)
chan->int_.auto_ && /* Shutoff enabled */ until = sim->vsu.freqmod.clocks;
chan->int_.clocks < until /* Shutoff */
) until = chan->int_.clocks;
if (
index == 4 && /* Channel 5 */
sim->vsu.freqmod.enb && /* Modifications enabled */
sim->vsu.freqmod.interval != 0 && /* Modifications valid */
sim->vsu.freqmod.clocks < until /* Next modification */
) until = sim->vsu.freqmod.clocks;
/* Manage clocks */ /* Manage clocks */
clocks -= until; clocks -= until;
chan->clocks -= until;
if (chan->env.enb)
chan->env.clocks -= until;
if (chan->int_.auto_)
chan->int_.clocks -= until;
if (freqmod)
sim->vsu.freqmod.clocks -= until;
/* Automatic shutoff */ /* Automatic shutoff */
if ( if (chan->int_.auto_ && chan->int_.clocks == 0) {
chan->int_.auto_ && /* Shutoff enabled */
chan->int_.clocks == until
) {
chan->int_.enb = 0; chan->int_.enb = 0;
return; return;
} }
/* Next sample */ /* Next sample */
if (chan->clocks == until) { if (chan->clocks == 0) {
/* Wave */ /* Wave */
if (index != 5) { if (index != 5) {
@ -161,10 +165,7 @@ static void vsuEmulateChannel(VB *sim, int index, uint32_t clocks) {
} }
/* Envelope modification */ /* Envelope modification */
if ( if (chan->env.enb && chan->env.clocks == 0) {
chan->env.enb && /* Modifications enabled */
chan->env.clocks == until
) {
if (chan->env.dir == 0 && chan->env.value != 0) if (chan->env.dir == 0 && chan->env.value != 0)
chan->env.value--; chan->env.value--;
else if (chan->env.dir == 1 && chan->env.value != 15) else if (chan->env.dir == 1 && chan->env.value != 15)
@ -172,16 +173,11 @@ static void vsuEmulateChannel(VB *sim, int index, uint32_t clocks) {
else if (chan->env.rep) else if (chan->env.rep)
chan->env.value = chan->env.reload; chan->env.value = chan->env.reload;
else chan->env.enb = 0; else chan->env.enb = 0;
chan->env.clocks = (uint32_t) chan->env.interval * 307220; chan->env.clocks = ((uint32_t) chan->env.interval + 1) * 307220;
} }
/* Frequency modification */ /* Frequency modification */
if ( if (freqmod && sim->vsu.freqmod.clocks == 0) {
index == 4 && /* Channel 5 */
sim->vsu.freqmod.enb && /* Modifications enabled */
sim->vsu.freqmod.interval != 0 && /* Modifications valid */
sim->vsu.freqmod.clocks == until
) {
chan->freq.current = sim->vsu.freqmod.next; chan->freq.current = sim->vsu.freqmod.next;
vsuNextFreqMod(sim, chan); vsuNextFreqMod(sim, chan);
if (!chan->int_.enb) if (!chan->int_.enb)
@ -222,7 +218,7 @@ static void vsuWriteEV1(VB *sim, int index, uint8_t value) {
case 4: /* Channel 5 */ case 4: /* Channel 5 */
sim->vsu.freqmod.enb = value >> 6 & 1; sim->vsu.freqmod.enb = value >> 6 & 1;
sim->vsu.freqmod.func = value >> 4 & 1; sim->vsu.freqmod.func = value >> 4 & 1;
sim->vsu.freqmod.rep = value >> 4 & 1; sim->vsu.freqmod.rep = value >> 5 & 1;
vsuNextFreqMod(sim, chan); vsuNextFreqMod(sim, chan);
break; break;