On 2015-06-04 03:06, Andrew Kelley wrote:
I open the audio playback device like this:
pa_threaded_mainloop_lock(audio_hardware->main_loop);
pa_sample_spec sample_spec;
sample_spec.format = to_pulseaudio_sample_format(sample_format);
sample_spec.rate = audio_device->default_sample_rate;
sample_spec.channels = audio_device->channel_layout.channel_count;
pa_channel_map channel_map =
to_pulseaudio_channel_map(&audio_device->channel_layout);
open_playback_device->stream =
pa_stream_new(audio_hardware->pulse_context,
"Genesis", &sample_spec, &channel_map);
// error handling omitted
pa_stream_set_state_callback(open_playback_device->stream,
playback_stream_state_callback,
open_playback_device);
pa_stream_set_write_callback(open_playback_device->stream,
playback_stream_write_callback,
open_playback_device);
pa_stream_set_underflow_callback(open_playback_device->stream,
playback_stream_underflow_callback,
open_playback_device);
open_playback_device->bytes_per_frame =
genesis_get_bytes_per_frame(sample_format,
audio_device->channel_layout.channel_count);
int bytes_per_second = open_playback_device->bytes_per_frame *
audio_device->default_sample_rate;
int buffer_length = open_playback_device->bytes_per_frame *
ceil(latency * bytes_per_second /
(double)open_playback_device->bytes_per_frame);
open_playback_device->buffer_attr.maxlength = buffer_length;
open_playback_device->buffer_attr.tlength = buffer_length;
open_playback_device->buffer_attr.prebuf = 0;
open_playback_device->buffer_attr.minreq = UINT32_MAX;
open_playback_device->buffer_attr.fragsize = UINT32_MAX;
pa_stream_connect_playback(open_playback_device->stream,
open_playback_device->audio_device->name,
&open_playback_device->buffer_attr,
PA_STREAM_ADJUST_LATENCY, nullptr, nullptr);
// error handling omitted
while (!open_playback_device->stream_ready)
pa_threaded_mainloop_wait(audio_hardware->main_loop);
pa_threaded_mainloop_unlock(audio_hardware->main_loop);
Here is some output from my program. When it prints UNDERRUN that means
the underflow callback was called. The number is the number of seconds
that the write callback took to fill the playback buffer. In this
example the audio device is opened with latency set to 10ms, e.g. 0.01
seconds. The percent is how long the callback took out of how long the
buffer size is. So that first UNDERRUN makes sense, because the callback
took 2x as long as it was supposed to. When an underrun occurs, the
playback buffer is filled completely with silence. So why am I getting
all these other underflow callbacks when the callback was well within
the range of time which should have been fine? Any ideas of things I can
do to troubleshoot?
If you set your total latency to 10 ms, minreq to -1, and include the
PA_STREAM_ADJUST_LATENCY flag, then the *total* latency is below 10 ms,
i e, including latency within PulseAudio itself.
PulseAudio will, for so small latency values, try to divide the 10 ms
into four periods of 2.5 ms each by default. After that these values
might be adjusted for various reasons.
If you want a *period* size of 10 ms, then you need to set minreq to 10
ms and tlength to something larger than 20 ms. But then again, PA is
free to change these values as it see fits (e g due to hardware
constraints).
Anyhow, if your callback is between 2.5 ms and (something less than) 10
ms, it's possible you get an underflow callback without there actually
being an audio glitch. There was a debate a while ago about whether it
would make sense to skip this underflow callback for this reason, but
IIRC, there was no consensus and thus the behaviour was not changed.
--
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic
_______________________________________________
pulseaudio-discuss mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss