Improve ZSM support by optimizing seek logic and using fractional CPU clocks. Also remove ZsmBackend::add_clocks, as it was no longer used, and caused issues when used.
This commit is contained in:
parent
d5d9ca8ce5
commit
b793fa949f
2 changed files with 26 additions and 43 deletions
|
@ -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);
|
||||
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);
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue