On Sun, 2011-06-19 at 11:53 +0200, Zeno Endemann wrote: > 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? Yes, I believe that's correct. But please use pa_usec_to_bytes(), it's easier to read :) > Should I file a bug report for the latency thing? Yes, please. > >> 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 ); > } That probably works fine, but I'd keep track of what was the original nbytes value and substract from it after calling pa_stream_write(). The if (!buf) check should be redundant. pa_stream_begin_write() never returns a null buffer unless you have made a mistake (see the checks at <http://cgit.freedesktop.org/pulseaudio/pulseaudio/tree/src/pulse/stream.c#n1384>) - if you don't trust yourself, you can break if pa_stream_begin_write() returns an error, or use an assertion. > >> 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... It shouldn't return a null pointer. Check the error code. > and wouldn't a neagtive offset mean that I loose some samples, > because they are written before the read position? For some reason it's not documented how the offset is interpreted, or at least I didn't find where it's said. I checked the code and it seemed that a negative offset would mean that the samples would be written after the read position, but I'm not 100% sure. -- Tanu