On Thu, 11.02.10 07:35, Tristin Celestin (tristin_celestin at yahoo.com) wrote: Heya, (there is something wrong with your mailer. It doesn't do proper line breaking.) > I managed to write a plugin that successfully delivers audio using > the normal pulseaudio API. I check the size of > pa_stream_writable_size every tick, and if it is below some > threshold, the application runs and produces sound. This threshold > right now is some magic number I stumbled upon, but I think it is > related to whatever tlength the server automatically gives me. You should not apply any threshold like this, and certainly not check whether _writable_size() is "below" it ("above" would be a better choice, but having any threshold but 0 is a bad idea). So what you should be doing is simply check whether _writable_size() is > 0, and if so supply at least as much data as this value, and you are free to pass more, in case your PCM generator is based on blocks of samples and you hence cannot provide the exact amount _writable_size() returned. > I can't write the plugin with the simple API, though, because the > only measure I have of the buffer state is pa_simple_get_latency, > and this doesn't seem to reflect the state of the sound buffer in > the same way that pa_stream_writable_size does. So, I assume I am > misunderstanding what "latency" means. I've never used an audio API > before, so I don't have any real understanding of the word, just a > sense of it from mailing lists and games. pa_stream_writable_size() will tell you how much data is missing in PA's buffers and which you need to supply quickly. pa_stream_get_latency() will tell you the delay that if you would call pa_stream_write() right after it how long it would take until the data you passed would begin to be audible. _writable_size() is measured in bytes. _get_latency() is measured in time units. For buffer management use the former. For time scheduling use the latter. > What happens here either there is a large period (~30 seconds to 90 > seconds) of silence before audio begins to play fine, or I get > bursts of audio (5-10 seconds) followed by very long bursts of > silence. I know this is related to prebuffering, but beyond that I > am lost. You are probably providing less data than _writable_size() asked you for. Note that PA is optimized for minimal battery/CPU usage. To achieve that in the ideal case we sleep for 1.9s and then ask all apps for 2s of data and then go to sleep until only 100ms are unplayed and ask for the full buffer fillup again. That means that PA will only ask you for data very very seldomly, which is probably what you are experiencing here. > So, in short: > 1. What is latency? The time d something you _write() at a time t takes to be played at a time t+d. Where "playing" means where the data is being turned into audible sound waves in your speakers. > 2. How do the meaning of pa_stream_writable_size and > pa_simple_get_latency differ in terms of the fill state of the > buffer? _writable_size() tells you directly about the fill level of your playback buffer. _get_latency() is indirectly related to _writable_size() but includes a lot of additional information. e.g. think of Bluetooth audio, where the local audio buffer is followed by another audio buffer in the headset before the audio is actually played. _get_latency() will try to cover the latency introduced by the latter buffer too, while _writable_size() just tells you how much data is currently missing and should be refilled by you in the former buffer. > 3. Would there be an objection to adding something along the lines > of pa_simple_writable_size? Does that even make sense? The simple API is a synchronous API. _writable_size() is useful only for asynchronous APIs. As such I don't think it makes much sense to add it to the simple API. Lennart -- Lennart Poettering Red Hat, Inc. lennart [at] poettering [dot] net http://0pointer.net/lennart/ GnuPG 0x1A015CC4