diff --git a/core/vb.c b/core/vb.c index ef0790b..12b7d3e 100644 --- a/core/vb.c +++ b/core/vb.c @@ -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) diff --git a/core/vsu.c b/core/vsu.c index db5fc14..283efa4 100644 --- a/core/vsu.c +++ b/core/vsu.c @@ -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;