diff mbox

[RESEND,2/3] pulseaudio: setup buffer attrs

Message ID 1295903266-6458-2-git-send-email-kraxel@redhat.com
State New
Headers show

Commit Message

Gerd Hoffmann Jan. 24, 2011, 9:07 p.m. UTC
Request reasonable buffer sizes from pulseaudio.  Without this
pa_simple_write() can block quite long and lead to dropouts,
especially with guests which use small audio ring buffers.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/paaudio.c |   12 +++++++++++-
 1 files changed, 11 insertions(+), 1 deletions(-)

Comments

Alon Levy Jan. 25, 2011, 9:20 a.m. UTC | #1
On Mon, Jan 24, 2011 at 10:07:45PM +0100, Gerd Hoffmann wrote:
> Request reasonable buffer sizes from pulseaudio.  Without this
> pa_simple_write() can block quite long and lead to dropouts,
> especially with guests which use small audio ring buffers.
> 
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  audio/paaudio.c |   12 +++++++++++-
>  1 files changed, 11 insertions(+), 1 deletions(-)
> 
> diff --git a/audio/paaudio.c b/audio/paaudio.c
> index 858ca81..75e3ea0 100644
> --- a/audio/paaudio.c
> +++ b/audio/paaudio.c
> @@ -289,6 +289,7 @@ static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as)
>  {
>      int error;
>      static pa_sample_spec ss;
> +    static pa_buffer_attr ba;
>      struct audsettings obt_as = *as;
>      PAVoiceOut *pa = (PAVoiceOut *) hw;
>  
> @@ -296,6 +297,15 @@ static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as)
>      ss.channels = as->nchannels;
>      ss.rate = as->freq;
>  
> +    /*
> +     * qemu audio tick runs at 250 Hz (by default), so processing
> +     * data chunks worth 4 ms of sound should be a good fit.
> +     */
> +    ba.tlength = pa_usec_to_bytes (4 * 1000, &ss);
> +    ba.minreq = pa_usec_to_bytes (2 * 1000, &ss);
> +    ba.maxlength = -1;
> +    ba.prebuf = -1;
> +

What's the default buffer size? Is there any reason to query this on startup
somewhere instead of hard coding it?

>      obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness);
>  
>      pa->s = pa_simple_new (
> @@ -306,7 +316,7 @@ static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as)
>          "pcm.playback",
>          &ss,
>          NULL,                   /* channel map */
> -        NULL,                   /* buffering attributes */
> +        &ba,                    /* buffering attributes */
>          &error
>          );
>      if (!pa->s) {
> -- 
> 1.7.1
> 
>
Gerd Hoffmann Jan. 25, 2011, 11:05 a.m. UTC | #2
Hi,

> What's the default buffer size?

Don't know the exact number, but pulse's default buffer size is quite 
big by design.  Which is fine for most apps (such as mp3 players) where 
loading more sound data into the buffer every second or so is ok.  It 
doesn't work very well for sound card emulation though.  And it doesn't 
work at all if your guest happens to use a ring buffer which holds sound 
data for only 20ms.

 > Is there any reason to query this on startup
 > somewhere instead of hard coding it?

No.  The pulse default values will never ever work for qemu's low 
latency requirements.

cheers,
   Gerd
diff mbox

Patch

diff --git a/audio/paaudio.c b/audio/paaudio.c
index 858ca81..75e3ea0 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -289,6 +289,7 @@  static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as)
 {
     int error;
     static pa_sample_spec ss;
+    static pa_buffer_attr ba;
     struct audsettings obt_as = *as;
     PAVoiceOut *pa = (PAVoiceOut *) hw;
 
@@ -296,6 +297,15 @@  static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as)
     ss.channels = as->nchannels;
     ss.rate = as->freq;
 
+    /*
+     * qemu audio tick runs at 250 Hz (by default), so processing
+     * data chunks worth 4 ms of sound should be a good fit.
+     */
+    ba.tlength = pa_usec_to_bytes (4 * 1000, &ss);
+    ba.minreq = pa_usec_to_bytes (2 * 1000, &ss);
+    ba.maxlength = -1;
+    ba.prebuf = -1;
+
     obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness);
 
     pa->s = pa_simple_new (
@@ -306,7 +316,7 @@  static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as)
         "pcm.playback",
         &ss,
         NULL,                   /* channel map */
-        NULL,                   /* buffering attributes */
+        &ba,                    /* buffering attributes */
         &error
         );
     if (!pa->s) {