On Wed, 13.05.09 10:28, Hynek Hanke (hanke at brailcom.org) wrote: > Hi Lennart, Heya, > we have tested it with 0.9.15 and got much better results. > Basically, it became fast enough with speech-dispatcher > now to be usable for accessibility. This is great! > > We are now at about 20ms latency with the 0.00+2*9.98+0.00 > values if we set tlength small enough, but without any glitches. > Cool! I still don't understand the zeros, but it seems to work. > > I'd like to ask how the connection settings influence the 3 buffer > lengths. Can we still do something to diminish the 9.98ms? > This seems to be the lowest value we can get regardless of > tlength and prebuf settings. Currently PA enforeces some limits on the samplign parameters: we will will sleep for at least 10 ms on each iteration and wakeup at least 4 ms before an underrun. I.e. with the current hardcoded settings you cannot get below 14ms unless you patch PA. Please note that without RT scheduling the lower latencies will almost never work properly. Due to security considerations we cannot enable RT sched by default, that's why we enforce this limits. > We are currently initializing the connection like this: > > pa_buffer_attr a_attr; > a_attr.maxlength = id->pulse_max_length; This should be initialized to (uint32_t) -1. This value has no influence on the latency. We probably shouldn't have exposed this parameter to the user in the first place. > a_attr.tlength = id->pulse_target_length; This is the most important value. If you set PA_STREAM_ADJUST_LATENCY (which you should) then this will directly control the overall latency. i.e. Set it to whatever latency you want and PA will try to come as close as it and the hw below can. If you do not set PA_STREAM_ADJUST_LATENCY then this will indirectly control the latency. It will directly control the size of the per-client playback buffer. Since the per-client software playback buffer cannot be smaller than then hardware playback buffer setting this value also has an influence on the size of the latter. > a_attr.prebuf = id->pulse_pre_buffering; This should be set to (uint32_t) -1 as well. If so this value will be initialized to the same value as the chosen tlength. Which is what makes most sense. We probably shouldn't have exposed this parameter to the user either. > a_attr.minreq = id->pulse_min_request; This should be set to (uint32_t) -1 as well. If you do PA will try to find a good value for you. > a_attr.fragsize = 0; > > if (pa_stream_connect_playback(id->pulse_stream, NULL, &a_attr, > (pa_stream_flags_t)(PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE), Set PA_STREAM_AJDUST_LATENCY inn the flags, too. > &id->pulse_volume, NULL) < 0) { Unless you have a very good reason to set the volume here, don't. Pass NULL instead. If so, PA will decide the volume on the server side and pick what it saved from the last time your application connected. This is highly recommended. Lennart -- Lennart Poettering Red Hat, Inc. lennart [at] poettering [dot] net http://0pointer.net/lennart/ GnuPG 0x1A015CC4