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) {
|
void ZsmBackend::tick(bool step) {
|
||||||
delayTicks -= 1;
|
delayTicks -= 1;
|
||||||
const double ClocksPerTick = ((double)HZ) / ((double)tick_rate);
|
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) {
|
while (delayTicks <= 0) {
|
||||||
ZsmCommand cmd = get_command();
|
ZsmCommand cmd = get_command();
|
||||||
switch (cmd.id) {
|
switch (cmd.id) {
|
||||||
|
@ -132,7 +134,7 @@ void ZsmBackend::tick(bool step) {
|
||||||
ticks_remaining -= clocksToAddForYm;
|
ticks_remaining -= clocksToAddForYm;
|
||||||
if (ticks_remaining < 0) {
|
if (ticks_remaining < 0) {
|
||||||
delayTicks -= 1;
|
delayTicks -= 1;
|
||||||
cpuClocks += ClocksPerTick;
|
nextCpuClocks += ClocksPerTick;
|
||||||
ticks_remaining += ClocksPerTick;
|
ticks_remaining += ClocksPerTick;
|
||||||
}
|
}
|
||||||
audio_step(clocksToAddForYm);
|
audio_step(clocksToAddForYm);
|
||||||
|
@ -205,38 +207,11 @@ void ZsmBackend::tick(bool step) {
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
audio_step(ticks_remaining);
|
size_t nextCpuClocksInt = std::floor(nextCpuClocks);
|
||||||
cpuClocks += ClocksPerTick;
|
size_t prevCpuClocksInt = std::floor(prevCpuClocks);
|
||||||
}
|
size_t cpuClocksIntDelta = nextCpuClocksInt - prevCpuClocksInt;
|
||||||
void ZsmBackend::add_clocks(double amount, bool step) {
|
audio_step(cpuClocksIntDelta);
|
||||||
const double ClocksPerTick = ((double)HZ) / ((double)tick_rate);
|
cpuClocks = std::fmod(nextCpuClocks, ClocksPerTick);
|
||||||
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 ZsmBackend::render(void *buf, size_t maxlen) {
|
size_t ZsmBackend::render(void *buf, size_t maxlen) {
|
||||||
size_t sample_type_len = 2;
|
size_t sample_type_len = 2;
|
||||||
|
@ -352,12 +327,20 @@ ZsmCommand::~ZsmCommand() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ZsmBackend::seek_internal(double position, bool loop) {
|
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);
|
file->seek(music_data_start, SeekType::SET);
|
||||||
this->cpuClocks = 0.0;
|
this->cpuClocks = 0.0;
|
||||||
this->delayTicks = 0;
|
this->delayTicks = 0;
|
||||||
this->ticks = 0.0;
|
this->ticks = 0.0;
|
||||||
this->position = 0.0;
|
this->position = 0.0;
|
||||||
|
} else if (this->position == position) {
|
||||||
|
audio_buf.clear();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
switch_stream(0);
|
||||||
|
}
|
||||||
while (this->position < position) {
|
while (this->position < position) {
|
||||||
audio_buf.clear();
|
audio_buf.clear();
|
||||||
try {
|
try {
|
||||||
|
@ -369,6 +352,7 @@ void ZsmBackend::seek_internal(double position, bool loop) {
|
||||||
this->delayTicks = 0;
|
this->delayTicks = 0;
|
||||||
this->ticks = 0.0;
|
this->ticks = 0.0;
|
||||||
this->position = 0.0;
|
this->position = 0.0;
|
||||||
|
audio_buf.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -376,7 +360,7 @@ void ZsmBackend::seek_internal(double position, bool loop) {
|
||||||
while (samples--) {
|
while (samples--) {
|
||||||
audio_buf.pop();
|
audio_buf.pop();
|
||||||
}
|
}
|
||||||
this->position = std::floor(position * PSG_FREQ) / PSG_FREQ;
|
this->position = position;
|
||||||
}
|
}
|
||||||
void ZsmBackend::seek(double position) {
|
void ZsmBackend::seek(double position) {
|
||||||
seek_internal(position, false);
|
seek_internal(position, false);
|
||||||
|
|
|
@ -155,8 +155,7 @@ class ZsmBackend : public PlaybackBackend {
|
||||||
inline double get_delay_per_frame() {
|
inline double get_delay_per_frame() {
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
void tick(bool step = true);
|
void tick(bool step = true);\
|
||||||
void add_clocks(double amount, bool step = true);
|
|
||||||
void seek_internal(double position, bool loop = true);
|
void seek_internal(double position, bool loop = true);
|
||||||
ZsmCommand get_command();
|
ZsmCommand get_command();
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in a new issue