[pulseaudio-discuss] My attempt to reduce latency with pacat and tvtime

Steven Elliott selliott4 at austin.rr.com
Mon Mar 26 21:54:37 PDT 2012


I use tvtime (an open source TV application) to watch TV on my Fedora 16
system.  As some of you may know forwarding audio from the sound card
built into the TV tuner card to the primary sound card is not done by
tvtime.  There are various ways of forwarding the audio including SoX,
module-loopback, etc. but I've had the best luck (least latency) using
pacat in a manner similar to what this webpage describes:

http://thelinuxexperiment.com/guinea-pigs/tyler-b/fix-pulseaudio-loopback-delay/

But with a change that I've made to pacat that I'd like to share in case
it's helpful.

The web page above describes using two instances of pacat with a pipe:
  pacat -r ... | pacat -p ...
to forward the audio.  I've found that this works quite well for a
while, but gradually the latency increases.  If for some reason the
pacat processes are temporarily suspended and then resumed (ctrl-Z
followed by bg, for example) the latency increases drastically.

I've found that the increased latency is due to audio queuing up on the
input to the play instance of pacat (the pacat on the right side of the
"|" shown above).  The extra queued up audio never gets consumed because
audio is being produced by the record instance of pacat (the pacat on
the left side of the "|" shown above) at the same rate it is consumed by
the play instance of pacat.  So I experimented with ways of discarding
the queued up audio that did not interfere with the sound quality too
much.

Each time stdin_callback() is called by the play instance of pacat to
get audio from the input pa_stream_writable_size() is called to see how
many bytes the sink can take.  This limits the amount of data that can
be read from stdin.

Each read of stdin is either full (precisely the number of bytes
requested is returned) or partial (less than the number of bytes
requested is returned).  I've found the if a large number of full reads
occur in a row that it's likely there latency due to extra audio queued
up in the input.  When this happens I've modified pacat to read as much
as 64 KiB more than what pa_stream_writable_size() requested, but then
discard the extra data read.

I suspect that there may be a more elegant solution at a different layer
in the code.  At the very least the change should be made optional so
that it does not break pacat when playing a file instead of reading from
a pipe:
  pacapt -p ... < audio.raw
But if there is interest I can add a command line option so that the
change is not always in effect.

-- 
------------------------------------------------------------------------
|  Steven Elliott  |  http://selliott.org  |  selliott4 at austin.rr.com  |
------------------------------------------------------------------------
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pacat-discard-experimental.diff
Type: text/x-patch
Size: 1902 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/pulseaudio-discuss/attachments/20120326/4ab14c29/attachment.bin>


More information about the pulseaudio-discuss mailing list