diff --git a/backends/playback/zsm/x16emu/vera_pcm.c b/backends/playback/zsm/x16emu/vera_pcm.c index 8dbe1e2..1e617c7 100644 --- a/backends/playback/zsm/x16emu/vera_pcm.c +++ b/backends/playback/zsm/x16emu/vera_pcm.c @@ -181,11 +181,22 @@ pcm_render(int16_t *buf, unsigned num_samples) } } uint32_t pcm_fifo_avail(void) { + uint32_t cnt_adj = fifo_cnt; switch ((ctrl >> 4) & 3) { - case 0: return fifo_cnt; - case 1: return fifo_cnt / 2; - case 2: return fifo_cnt / 2; - case 3: return fifo_cnt / 4; + case 3: cnt_adj /= 2; + case 2: + case 1: cnt_adj /= 2; + case 0: break; } - return 0; + uint32_t output = 0; + uint32_t _phase = phase; + while (cnt_adj != 0) { + uint32_t _prev_phase = _phase; + _phase += rate; + if ((_phase & 0x80) != (_prev_phase & 0x80)) { + output++; + cnt_adj--; + } + } + return output; } diff --git a/backends/playback/zsm/zsm_backend.hpp b/backends/playback/zsm/zsm_backend.hpp index c6a37f8..1db5771 100644 --- a/backends/playback/zsm/zsm_backend.hpp +++ b/backends/playback/zsm/zsm_backend.hpp @@ -84,22 +84,23 @@ class ZsmBackend : public PlaybackBackend { return (int16_t)((((int32_t)a) + ((int32_t)b)) >> 1); } void audio_step(size_t samples) { - while (pcm_fifo_avail() < samples && remain > 0) { - remain--; - size_t oldpos = file->get_pos(); - file->seek((cur++), SeekType::SET); - uint8_t sample; - file->read(&sample, 1, 1); - pcm_write_fifo(sample); - if (remain == 0) { - if (islooped) { - cur = loop; - remain = loop_rem; - } - } - file->seek(oldpos, SeekType::SET); - } if (samples == 0) return; + while (pcm_fifo_avail() < samples && remain > 0) { + if (pcm_read_rate() == 0) break; + remain--; + size_t oldpos = file->get_pos(); + file->seek((cur++), SeekType::SET); + uint8_t sample; + file->read(&sample, 1, 1); + pcm_write_fifo(sample); + if (remain == 0) { + if (islooped) { + cur = loop; + remain = loop_rem; + } + } + file->seek(oldpos, SeekType::SET); + } samples *= 2; int16_t *psg_ptr = psg_buf.get_item_sized(samples); int16_t *pcm_ptr = pcm_buf.get_item_sized(samples);