mirror of
https://github.com/holub/mame
synced 2025-04-26 18:23:08 +03:00
Suggestion for very-low-latency mode on portaudio
- Needed to keep audio in sync when playing rhythm game machines such as konami system 573. This is because the lowest audio_latency currently supported (audio_latency 1) introduces at least 10 ms of variable latency. I am unsure how to go about this without breaking backward compatibility so I set it to work only when audio_latency is 0 (which was previously ignored by mame itself and was treated equivalent to audio_latency 1). I am aware that setting audio_latency to 0 is not supported by many mame frontends, but this change seems natural. Otherwise, would it be better to add a new mame.ini option, or to automatically enable this low-latency mode when pa_latency is set lower than, say, 0.01 (10ms), which would break people's configurations if they already rely on the old behavior?
This commit is contained in:
parent
a5fdcb40f8
commit
1ccdfb873a
@ -132,7 +132,7 @@ private:
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
LATENCY_MIN = 1,
|
LATENCY_MIN = 0,
|
||||||
LATENCY_MAX = 5,
|
LATENCY_MAX = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -261,8 +261,16 @@ int sound_pa::init(osd_options const &options)
|
|||||||
// clamp to a probable figure
|
// clamp to a probable figure
|
||||||
callback_interval = std::min<double>(callback_interval, 20.0);
|
callback_interval = std::min<double>(callback_interval, 20.0);
|
||||||
|
|
||||||
// set the best guess callback interval to allowed count, each audio_latency step > 1 adds 20 ms
|
if (m_audio_latency == 0)
|
||||||
m_skip_threshold = ((std::max<double>(callback_interval, 10.0) + (m_audio_latency - 1) * 20.0) / 1000.0) * m_sample_rate * 2 + 0.5f;
|
{
|
||||||
|
// very-low-latency mode (set audio_latency to 0); pa_latency controls allowable audio jitter
|
||||||
|
m_skip_threshold = (options.pa_latency() ? options.pa_latency() : device_info->defaultLowOutputLatency) * m_sample_rate * 2 + 0.5f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// set the best guess callback interval to allowed count, each audio_latency step > 1 adds 20 ms
|
||||||
|
m_skip_threshold = ((std::max<double>(callback_interval, 10.0) + (m_audio_latency - 1) * 20.0) / 1000.0) * m_sample_rate * 2 + 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
osd_printf_verbose("PortAudio: Using device \"%s\" on API \"%s\"\n", device_info->name, api_info->name);
|
osd_printf_verbose("PortAudio: Using device \"%s\" on API \"%s\"\n", device_info->name, api_info->name);
|
||||||
osd_printf_verbose("PortAudio: Sample rate is %0.0f Hz, device output latency is %0.2f ms\n",
|
osd_printf_verbose("PortAudio: Sample rate is %0.0f Hz, device output latency is %0.2f ms\n",
|
||||||
@ -343,13 +351,24 @@ int sound_pa::callback(s16* output_buffer, size_t number_of_samples)
|
|||||||
// if we have been above the set threshold for ~1 second, skip forward
|
// if we have been above the set threshold for ~1 second, skip forward
|
||||||
if (m_osd_ticks - m_skip_threshold_ticks > m_osd_tps)
|
if (m_osd_ticks - m_skip_threshold_ticks > m_osd_tps)
|
||||||
{
|
{
|
||||||
int adjust = m_buffer_min_ct - m_skip_threshold / 2;
|
if (m_audio_latency == 0)
|
||||||
|
{
|
||||||
// if adjustment is less than two milliseconds, don't bother
|
// in very-low-latency mode, always skip forward the whole way
|
||||||
if (adjust / 2 > sample_rate() / 500) {
|
// to prevent input from appearing delayed (due to sound cues getting delayed)
|
||||||
m_ab->increment_playpos(adjust);
|
m_ab->increment_playpos(m_buffer_min_ct);
|
||||||
|
//osd_printf_verbose("PortAudio: skip ahead %d samples\n", m_buffer_min_ct);
|
||||||
m_has_overflowed = true;
|
m_has_overflowed = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int adjust = m_buffer_min_ct - m_skip_threshold / 2;
|
||||||
|
|
||||||
|
// if adjustment is less than two milliseconds, don't bother
|
||||||
|
if (adjust / 2 > sample_rate() / 500) {
|
||||||
|
m_ab->increment_playpos(adjust);
|
||||||
|
m_has_overflowed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_skip_threshold_ticks = m_osd_ticks;
|
m_skip_threshold_ticks = m_osd_ticks;
|
||||||
m_buffer_min_ct = INT_MAX;
|
m_buffer_min_ct = INT_MAX;
|
||||||
|
Loading…
Reference in New Issue
Block a user