[pulseaudio-discuss] Async API - need some help

Zeno Endemann zeno.endemann at googlemail.com
Sun Jun 19 02:53:13 PDT 2011


On 2011-06-19 10:48, Tanu Kaskinen wrote:
> On Sun, 2011-06-19 at 11:28 +0300, Tanu Kaskinen wrote:
>> 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?)
> 
> Uh, I'm talking nonsense here. tlength is given in bytes. Your
> conversion is broken still, though. What I said about the effective
> tlength not being what was requested is not true - pulseaudio does seem
> to work correctly here (the effective tlength is less than what is
> requested, but I'd guess that the sink latency is getting substracted
> from the requested length). Latency reporting is still broken.
> 

Thanks for the help! The correct formula for tlength should be
latency * 2 * sspec.channels * sspec.rate / 1000, right?
Should I file a bug report for the latency thing?

>> 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).

Hm, the following code seems to work, did you mean it like this:
    while( pa_stream_writable_size(p) > 0) {
        pa_stream_begin_write(p, (void **)&buf, &nbytes);
        if( ! buf )
            break;
        writeToneToBuffer(buf, nbytes/4, cs);
        pa_stream_write(p, buf, (nbytes/4)*4, 0, 0, PA_SEEK_RELATIVE );
    }

>> 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).

I tried using pa_stream_begin_write, but it always returns a nullpointer
there... and wouldn't a neagtive offset mean that I loose some samples,
because they are written before the read position?

Thanks again,
Zeno


More information about the pulseaudio-discuss mailing list