diff --git a/backends/playback/zsm/zsm_backend.cpp b/backends/playback/zsm/zsm_backend.cpp index 1a0876a..33c5c21 100644 --- a/backends/playback/zsm/zsm_backend.cpp +++ b/backends/playback/zsm/zsm_backend.cpp @@ -109,7 +109,9 @@ void ZsmBackend::cleanup() { void ZsmBackend::tick(bool step) { delayTicks -= 1; const double ClocksPerTick = ((double)HZ) / ((double)tick_rate); - ssize_t ticks_remaining = ClocksPerTick; + double prevCpuClocks = cpuClocks; + double nextCpuClocks = cpuClocks + ClocksPerTick; + double ticks_remaining = ClocksPerTick; while (delayTicks <= 0) { ZsmCommand cmd = get_command(); switch (cmd.id) { @@ -132,7 +134,7 @@ void ZsmBackend::tick(bool step) { ticks_remaining -= clocksToAddForYm; if (ticks_remaining < 0) { delayTicks -= 1; - cpuClocks += ClocksPerTick; + nextCpuClocks += ClocksPerTick; ticks_remaining += ClocksPerTick; } audio_step(clocksToAddForYm); @@ -205,38 +207,11 @@ void ZsmBackend::tick(bool step) { } break; } } - audio_step(ticks_remaining); - cpuClocks += ClocksPerTick; -} -void ZsmBackend::add_clocks(double amount, bool step) { - const double ClocksPerTick = ((double)HZ) / ((double)tick_rate); - cpuClocks = std::fmod(cpuClocks, ClocksPerTick); - double prevCpuClocks = cpuClocks; - size_t prevIntCpuClocks = prevCpuClocks; - double tickDelta = amount / ClocksPerTick; - double prevTicks = ticks; - ticks += tickDelta; - size_t prevIntTicks = prevTicks; - size_t intTicks = ticks; - size_t intTicksDelta = intTicks - prevIntTicks; - cpuClocks += intTicks * ClocksPerTick; - double remainder = amount - (intTicksDelta * ClocksPerTick); - size_t intCpuClocks = cpuClocks; - size_t intCpuClockDelta = intCpuClocks - prevIntCpuClocks; - double initialTicks = prevCpuClocks / ClocksPerTick; - for (size_t i = 0; i < intTicksDelta; i++) { - double preTickCpuClocks = cpuClocks; - delayTicks--; - tick(step); - double neededCpuClocks = preTickCpuClocks + ClocksPerTick; - if (cpuClocks < neededCpuClocks) { - cpuClocks = neededCpuClocks; - } - } - if (remainder >= 0) { - cpuClocks += remainder; - audio_step(remainder); - } + size_t nextCpuClocksInt = std::floor(nextCpuClocks); + size_t prevCpuClocksInt = std::floor(prevCpuClocks); + size_t cpuClocksIntDelta = nextCpuClocksInt - prevCpuClocksInt; + audio_step(cpuClocksIntDelta); + cpuClocks = std::fmod(nextCpuClocks, ClocksPerTick); } size_t ZsmBackend::render(void *buf, size_t maxlen) { size_t sample_type_len = 2; @@ -352,12 +327,20 @@ ZsmCommand::~ZsmCommand() { } } void ZsmBackend::seek_internal(double position, bool loop) { - switch_stream(0); - file->seek(music_data_start, SeekType::SET); - this->cpuClocks = 0.0; - this->delayTicks = 0; - this->ticks = 0.0; - this->position = 0.0; + this->position = std::floor(this->position * PSG_FREQ) / PSG_FREQ; + position = std::floor(position * PSG_FREQ) / PSG_FREQ; + if (this->position > position) { + file->seek(music_data_start, SeekType::SET); + this->cpuClocks = 0.0; + this->delayTicks = 0; + this->ticks = 0.0; + this->position = 0.0; + } else if (this->position == position) { + audio_buf.clear(); + return; + } else { + switch_stream(0); + } while (this->position < position) { audio_buf.clear(); try { @@ -369,6 +352,7 @@ void ZsmBackend::seek_internal(double position, bool loop) { this->delayTicks = 0; this->ticks = 0.0; this->position = 0.0; + audio_buf.clear(); return; } } @@ -376,7 +360,7 @@ void ZsmBackend::seek_internal(double position, bool loop) { while (samples--) { audio_buf.pop(); } - this->position = std::floor(position * PSG_FREQ) / PSG_FREQ; + this->position = position; } void ZsmBackend::seek(double position) { seek_internal(position, false); diff --git a/backends/playback/zsm/zsm_backend.hpp b/backends/playback/zsm/zsm_backend.hpp index f03cca4..d8f0286 100644 --- a/backends/playback/zsm/zsm_backend.hpp +++ b/backends/playback/zsm/zsm_backend.hpp @@ -155,8 +155,7 @@ class ZsmBackend : public PlaybackBackend { inline double get_delay_per_frame() { return 1.0; } - void tick(bool step = true); - void add_clocks(double amount, bool step = true); + void tick(bool step = true);\ void seek_internal(double position, bool loop = true); ZsmCommand get_command(); public: