[pulseaudio-discuss] Async API - need some help

Tanu Kaskinen tanuk at iki.fi
Sun Jun 19 01:28:11 PDT 2011


On Sat, 2011-06-18 at 23:29 +0200, Zeno Endemann wrote:
> Hello everyone,
> 
> I've written a small Qt application for pulseaudio latency testing. It
> already somewhat works, but I still have a few issues:
> 
> 1. The following code fragment works (audio is played):
>     int16_t *buf = (int16_t *)malloc(nbytes);
>     writeToneToBuffer(buf, nbytes/4, ...);
>     pa_stream_write(p, buf, (nbytes/4)*4, 0, 0, PA_SEEK_RELATIVE );
>     free(buf);
> whereas this does not:
>     int16_t *buf = 0;
>     pa_stream_begin_write(p, (void **)&buf, &nbytes);
>     writeToneToBuffer(buf, nbytes/4, ...);
>     pa_stream_write(p, buf, (nbytes/4)*4, 0, 0, PA_SEEK_RELATIVE );
> There is no error reported, just no audio is played. Do I need to do
> something else?

It seems to work fine if I set the latency to some low value. With
higher latencies the problem is that pa_stream_begin_write() returns a
buffer that is much smaller than the original request size, and it's not
enough to fill the buffer to the prebuf limit. Since the prebuffering
never ends, the stream never starts playing. You should make multiple
writes until the buffer is full (ie. pa_stream_writable_size returns 0).

> 2. I figure it should be possible to react fast to user input even when
> the playback buffers are big by overwriting already written buffers with
> pa_stream_write(..., buf, ..., offset, PA_SEEK_RELATIVE_ON_READ). But
> how big can/should buf and offset be? So far I haven't been able to get
> good results with this (either underruns are reported or the latency
> remains quite bad).

I don't have any advice for the offset, sorry. It would be good to have
some example code for doing rewrites... For buf size, I'd guess pretty
large buffers would be good. If you can use
pa_stream_begin_write(nbytes=-1), use it and fill the whole buffer it
gives you, or if you use a small buffer, you'll probably want to limit
the amount you write to tlength + offset (offset being a negative
number).

> 3. To print out latency measurements I use the following code:
>    if( pa_stream_get_latency(cs->pa_Strm, &l, &neg) == PA_ERR_NODATA )
>      qDebug("error: no data");
>    else
>      qDebug("Latency: %d", (int)l);
> but this always gives me weird, much too big numbers.

If I set latency to -1, the numbers seem sensible. Otherwise it looks
like something is very broken in pulseaudio... Same goes for the
effective buffer attributes: I printed what pa_stream_get_buffer_attr()
returns when the stream is ready, and the tlength didn't really seem to
correspond to what the application requested.

Btw, pa_buffer_attr.tlength is given in microseconds, but you pass the
number in the UI without converting it, and since the ui doesn't let me
choose bigger numbers than 2000, the maximum tlength is 8000
microseconds... (Why do you multiply the number with 4, btw?)

-- 
Tanu



More information about the pulseaudio-discuss mailing list