This is damn sensitive code, and generates differences all over the
place we don't really explain.  The changes should be justified by
themselves and tested in collaboration with Tafoid to ensure the
differences are not a problem.
This commit is contained in:
Olivier Galibert 2018-07-29 13:07:56 +02:00
parent a74434167a
commit 64afd77e7c
2 changed files with 33 additions and 57 deletions

View File

@ -452,12 +452,7 @@ void device_scheduler::timeslice()
{
// only process if this CPU is executing or truly halted (not yielding)
// and if our target is later than the CPU's current time (coarse check)
if (exec->m_suspend != 0)
{
if (exec->m_eatcycles)
exec->m_localtime = target;
}
else if (target.seconds() >= exec->m_localtime.seconds())
if (EXPECTED((exec->m_suspend == 0 || exec->m_eatcycles) && target.seconds() >= exec->m_localtime.seconds()))
{
// compute how many attoseconds to execute this CPU
attoseconds_t delta = target.attoseconds() - exec->m_localtime.attoseconds();
@ -472,28 +467,32 @@ void device_scheduler::timeslice()
int ran = exec->m_cycles_running = divu_64x32(u64(delta) >> exec->m_divshift, exec->m_divisor);
LOG((" cpu '%s': %d (%d cycles)\n", exec->device().tag(), delta, exec->m_cycles_running));
g_profiler.start(exec->m_profiler);
// note that this global variable cycles_stolen can be modified
// via the call to cpu_execute
exec->m_cycles_stolen = 0;
m_executing_device = exec;
*exec->m_icountptr = exec->m_cycles_running;
if (!call_debugger)
exec->run();
else
// if we're not suspended, actually execute
if (exec->m_suspend == 0)
{
exec->debugger_start_cpu_hook(target);
exec->run();
exec->debugger_stop_cpu_hook();
}
g_profiler.start(exec->m_profiler);
// adjust for any cycles we took back
assert(ran >= *exec->m_icountptr);
ran -= *exec->m_icountptr;
assert(ran >= exec->m_cycles_stolen);
ran -= exec->m_cycles_stolen;
g_profiler.stop();
// note that this global variable cycles_stolen can be modified
// via the call to cpu_execute
exec->m_cycles_stolen = 0;
m_executing_device = exec;
*exec->m_icountptr = exec->m_cycles_running;
if (!call_debugger)
exec->run();
else
{
exec->debugger_start_cpu_hook(target);
exec->run();
exec->debugger_stop_cpu_hook();
}
// adjust for any cycles we took back
assert(ran >= *exec->m_icountptr);
ran -= *exec->m_icountptr;
assert(ran >= exec->m_cycles_stolen);
ran -= exec->m_cycles_stolen;
g_profiler.stop();
}
// account for these cycles
exec->m_totalcycles += ran;

View File

@ -264,9 +264,6 @@ void sound_stream::set_input(int index, sound_stream *input_stream, int output_i
void sound_stream::update()
{
if (!m_attoseconds_per_sample)
return;
// determine the number of samples since the start of this second
attotime time = m_device.machine().time();
s32 update_sampindex = s32(time.attoseconds() / m_attoseconds_per_sample);
@ -442,17 +439,8 @@ void sound_stream::apply_sample_rate_changes()
recompute_sample_rate_data();
// reset our sample indexes to the current time
if (old_rate)
{
m_output_sampindex = s64(m_output_sampindex) * s64(m_sample_rate) / old_rate;
m_output_update_sampindex = s64(m_output_update_sampindex) * s64(m_sample_rate) / old_rate;
}
else
{
m_output_sampindex = m_device.machine().sound().last_update().attoseconds() / m_attoseconds_per_sample;
m_output_update_sampindex = m_output_sampindex;
}
m_output_sampindex = s64(m_output_sampindex) * s64(m_sample_rate) / old_rate;
m_output_update_sampindex = s64(m_output_update_sampindex) * s64(m_sample_rate) / old_rate;
m_output_base_sampindex = m_output_sampindex - m_max_samples_per_update;
// clear out the buffer
@ -483,22 +471,15 @@ void sound_stream::recompute_sample_rate_data()
throw emu_fatalerror("Incompatible sample rates as input of a synchronous stream: %d and %d\n", m_sample_rate, input.m_source->m_stream->m_sample_rate);
}
}
if (!m_sample_rate)
m_sample_rate = 1000;
}
// recompute the timing parameters
attoseconds_t update_attoseconds = m_device.machine().sound().update_attoseconds();
if (m_sample_rate)
{
m_attoseconds_per_sample = ATTOSECONDS_PER_SECOND / m_sample_rate;
m_max_samples_per_update = (update_attoseconds + m_attoseconds_per_sample - 1) / m_attoseconds_per_sample;
}
else
{
m_attoseconds_per_sample = 0;
m_max_samples_per_update = 0;
}
m_attoseconds_per_sample = ATTOSECONDS_PER_SECOND / m_sample_rate;
m_max_samples_per_update = (update_attoseconds + m_attoseconds_per_sample - 1) / m_attoseconds_per_sample;
// update resample and output buffer sizes
allocate_resample_buffers();
@ -509,7 +490,7 @@ void sound_stream::recompute_sample_rate_data()
{
// if we have a source, see if its sample rate changed
if (input.m_source != nullptr && input.m_source->m_stream->m_sample_rate)
if (input.m_source != nullptr)
{
// okay, we have a new sample rate; recompute the latency to be the maximum
// sample period between us and our input
@ -530,10 +511,6 @@ void sound_stream::recompute_sample_rate_data()
input.m_latency_attoseconds = std::max(input.m_latency_attoseconds, latency);
assert(input.m_latency_attoseconds < update_attoseconds);
}
else
{
input.m_latency_attoseconds = 0;
}
}
// If synchronous, prime the timer
@ -676,7 +653,7 @@ stream_sample_t *sound_stream::generate_resampled_data(stream_input &input, u32
{
// if we don't have an output to pull data from, generate silence
stream_sample_t *dest = &input.m_resample[0];
if (input.m_source == nullptr || input.m_source->m_buffer.size() == 0)
if (input.m_source == nullptr)
{
memset(dest, 0, numsamples * sizeof(*dest));
return &input.m_resample[0];