mirror of
https://github.com/holub/mame
synced 2025-05-29 17:13:05 +03:00
Fix setting sample rate back to zero & crash for synchronous streams when rate is zero. This fixes all reported bugs. (nw)
This commit is contained in:
parent
64afd77e7c
commit
3a732c9b1c
@ -452,7 +452,12 @@ 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 (EXPECTED((exec->m_suspend == 0 || exec->m_eatcycles) && target.seconds() >= exec->m_localtime.seconds()))
|
||||
if (exec->m_suspend != 0)
|
||||
{
|
||||
if (exec->m_eatcycles)
|
||||
exec->m_localtime = target;
|
||||
}
|
||||
else if (target.seconds() >= exec->m_localtime.seconds())
|
||||
{
|
||||
// compute how many attoseconds to execute this CPU
|
||||
attoseconds_t delta = target.attoseconds() - exec->m_localtime.attoseconds();
|
||||
@ -467,9 +472,6 @@ 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));
|
||||
|
||||
// if we're not suspended, actually execute
|
||||
if (exec->m_suspend == 0)
|
||||
{
|
||||
g_profiler.start(exec->m_profiler);
|
||||
|
||||
// note that this global variable cycles_stolen can be modified
|
||||
@ -492,7 +494,6 @@ void device_scheduler::timeslice()
|
||||
assert(ran >= exec->m_cycles_stolen);
|
||||
ran -= exec->m_cycles_stolen;
|
||||
g_profiler.stop();
|
||||
}
|
||||
|
||||
// account for these cycles
|
||||
exec->m_totalcycles += ran;
|
||||
|
@ -53,7 +53,7 @@ sound_stream::sound_stream(device_t &device, int inputs, int outputs, int sample
|
||||
: m_device(device),
|
||||
m_next(nullptr),
|
||||
m_sample_rate(sample_rate),
|
||||
m_new_sample_rate(0),
|
||||
m_new_sample_rate(0xffffffff),
|
||||
m_attoseconds_per_sample(0),
|
||||
m_max_samples_per_update(0),
|
||||
m_input(inputs),
|
||||
@ -264,6 +264,9 @@ 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);
|
||||
@ -427,23 +430,33 @@ void sound_stream::update_with_accounting(bool second_tick)
|
||||
void sound_stream::apply_sample_rate_changes()
|
||||
{
|
||||
// skip if nothing to do
|
||||
if (m_new_sample_rate == 0)
|
||||
if (m_new_sample_rate == 0xffffffff)
|
||||
return;
|
||||
|
||||
// update to the new rate and remember the old rate
|
||||
u32 old_rate = m_sample_rate;
|
||||
m_sample_rate = m_new_sample_rate;
|
||||
m_new_sample_rate = 0;
|
||||
m_new_sample_rate = 0xffffffff;
|
||||
|
||||
// recompute all the data
|
||||
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_attoseconds_per_sample ? m_device.machine().sound().last_update().attoseconds() / m_attoseconds_per_sample : 0;
|
||||
m_output_update_sampindex = m_output_sampindex;
|
||||
}
|
||||
|
||||
m_output_base_sampindex = m_output_sampindex - m_max_samples_per_update;
|
||||
|
||||
// clear out the buffer
|
||||
if (m_max_samples_per_update)
|
||||
for (auto & elem : m_output)
|
||||
memset(&elem.m_buffer[0], 0, m_max_samples_per_update * sizeof(elem.m_buffer[0]));
|
||||
}
|
||||
@ -471,15 +484,22 @@ 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;
|
||||
}
|
||||
|
||||
// update resample and output buffer sizes
|
||||
allocate_resample_buffers();
|
||||
@ -490,7 +510,7 @@ void sound_stream::recompute_sample_rate_data()
|
||||
{
|
||||
// if we have a source, see if its sample rate changed
|
||||
|
||||
if (input.m_source != nullptr)
|
||||
if (input.m_source != nullptr && input.m_source->m_stream->m_sample_rate)
|
||||
{
|
||||
// okay, we have a new sample rate; recompute the latency to be the maximum
|
||||
// sample period between us and our input
|
||||
@ -511,15 +531,24 @@ 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
|
||||
if (m_synchronous)
|
||||
{
|
||||
attotime time = m_device.machine().time();
|
||||
if (m_attoseconds_per_sample)
|
||||
{
|
||||
attoseconds_t next_edge = m_attoseconds_per_sample - (time.attoseconds() % m_attoseconds_per_sample);
|
||||
m_sync_timer->adjust(attotime(0, next_edge));
|
||||
}
|
||||
else
|
||||
m_sync_timer->adjust(attotime::never);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -587,7 +616,7 @@ void sound_stream::postload()
|
||||
memset(&elem.m_buffer[0], 0, m_output_bufalloc * sizeof(elem.m_buffer[0]));
|
||||
|
||||
// recompute the sample indexes to make sense
|
||||
m_output_sampindex = m_device.machine().sound().last_update().attoseconds() / m_attoseconds_per_sample;
|
||||
m_output_sampindex = m_attoseconds_per_sample ? m_device.machine().sound().last_update().attoseconds() / m_attoseconds_per_sample : 0;
|
||||
m_output_update_sampindex = m_output_sampindex;
|
||||
m_output_base_sampindex = m_output_sampindex - m_max_samples_per_update;
|
||||
}
|
||||
@ -653,7 +682,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)
|
||||
if (input.m_source == nullptr || input.m_source->m_stream->m_attoseconds_per_sample == 0)
|
||||
{
|
||||
memset(dest, 0, numsamples * sizeof(*dest));
|
||||
return &input.m_resample[0];
|
||||
|
Loading…
Reference in New Issue
Block a user