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 */
VBAPI void* vbGetSamples(VB *sim, uint32_t *capacity, uint32_t *position) {
if (capacity == NULL) {
if (sim->vsu.out.samples == NULL) {
if (capacity != NULL)
*capacity = 0;
if (position != NULL)

View File

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