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