All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Volker Rümelin" <vr_qemu@t-online.de>,
	"Gerd Hoffmann" <kraxel@redhat.com>,
	"Markus Armbruster" <armbru@redhat.com>
Subject: [PULL 13/30] paaudio: avoid to clip samples multiple times
Date: Fri, 15 Jan 2021 14:21:29 +0100	[thread overview]
Message-ID: <20210115132146.1443592-14-kraxel@redhat.com> (raw)
In-Reply-To: <20210115132146.1443592-1-kraxel@redhat.com>

From: Volker Rümelin <vr_qemu@t-online.de>

The pulseaudio backend currently converts, clips and copies audio
playback samples in the mixing-engine sample buffer multiple
times.

In qpa_get_buffer_out() the function pa_stream_begin_write()
returns a rather large buffer and this allows audio_pcm_hw_run_out()
in audio/audio.c to copy all samples in the mixing-engine buffer
to the pulse audio buffer. Immediately after copying, qpa_write()
notices with a call to pa_stream_writable_size() that pulse audio
only needs a smaller part of the copied samples and ignores the
rest. This copy and ignore process happens several times for each
audio sample.

To fix this behaviour, call pa_stream_writable_size() in
qpa_get_buffer_out() to limit the number of samples
audio_pcm_hw_run_out() will convert. With this change the
pulseaudio pcm_ops functions put_buffer_out and write are no
longer identical and a separate qpa_put_buffer_out is needed.

Signed-off-by: Volker Rümelin <vr_qemu@t-online.de>
Message-id: 9315afe5-5958-c0b4-ea1e-14769511a9d5@t-online.de
Message-Id: <20210110100239.27588-13-vr_qemu@t-online.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 audio/paaudio.c | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/audio/paaudio.c b/audio/paaudio.c
index b05208469831..229bcfcae838 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -207,6 +207,7 @@ static void *qpa_get_buffer_out(HWVoiceOut *hw, size_t *size)
     PAVoiceOut *p = (PAVoiceOut *) hw;
     PAConnection *c = p->g->conn;
     void *ret;
+    size_t l;
     int r;
 
     pa_threaded_mainloop_lock(c->mainloop);
@@ -214,12 +215,19 @@ static void *qpa_get_buffer_out(HWVoiceOut *hw, size_t *size)
     CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
                     "pa_threaded_mainloop_lock failed\n");
 
+    l = pa_stream_writable_size(p->stream);
+    CHECK_SUCCESS_GOTO(c, l != (size_t) -1, unlock_and_fail,
+                       "pa_stream_writable_size failed\n");
+
     *size = -1;
     r = pa_stream_begin_write(p->stream, &ret, size);
     CHECK_SUCCESS_GOTO(c, r >= 0, unlock_and_fail,
                        "pa_stream_begin_write failed\n");
 
     pa_threaded_mainloop_unlock(c->mainloop);
+    if (*size > l) {
+        *size = l;
+    }
     return ret;
 
 unlock_and_fail:
@@ -228,6 +236,28 @@ unlock_and_fail:
     return NULL;
 }
 
+static size_t qpa_put_buffer_out(HWVoiceOut *hw, void *data, size_t length)
+{
+    PAVoiceOut *p = (PAVoiceOut *)hw;
+    PAConnection *c = p->g->conn;
+    int r;
+
+    pa_threaded_mainloop_lock(c->mainloop);
+
+    CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
+                    "pa_threaded_mainloop_lock failed\n");
+
+    r = pa_stream_write(p->stream, data, length, NULL, 0LL, PA_SEEK_RELATIVE);
+    CHECK_SUCCESS_GOTO(c, r >= 0, unlock_and_fail, "pa_stream_write failed\n");
+
+    pa_threaded_mainloop_unlock(c->mainloop);
+    return length;
+
+unlock_and_fail:
+    pa_threaded_mainloop_unlock(c->mainloop);
+    return 0;
+}
+
 static size_t qpa_write(HWVoiceOut *hw, void *data, size_t length)
 {
     PAVoiceOut *p = (PAVoiceOut *) hw;
@@ -861,7 +891,7 @@ static struct audio_pcm_ops qpa_pcm_ops = {
     .fini_out = qpa_fini_out,
     .write    = qpa_write,
     .get_buffer_out = qpa_get_buffer_out,
-    .put_buffer_out = qpa_write, /* pa handles it */
+    .put_buffer_out = qpa_put_buffer_out,
     .volume_out = qpa_volume_out,
 
     .init_in  = qpa_init_in,
-- 
2.29.2



  parent reply	other threads:[~2021-01-15 14:01 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-15 13:21 [PULL 00/30] Audio 20210115 patches Gerd Hoffmann
2021-01-15 13:21 ` [PULL 01/30] sdlaudio: remove leftover SDL1.2 code Gerd Hoffmann
2021-01-15 13:21 ` [PULL 02/30] audio: fix bit-rotted code Gerd Hoffmann
2021-01-15 13:21 ` [PULL 03/30] sdlaudio: add -audiodev sdl,out.buffer-count option Gerd Hoffmann
2021-01-15 13:21 ` [PULL 04/30] sdlaudio: don't start playback in init routine Gerd Hoffmann
2021-01-15 13:21 ` [PULL 05/30] sdlaudio: always clear the sample buffer Gerd Hoffmann
2021-01-15 13:21 ` [PULL 06/30] sdlaudio: fill remaining sample buffer with silence Gerd Hoffmann
2021-01-15 13:21 ` [PULL 07/30] sdlaudio: replace legacy functions with modern ones Gerd Hoffmann
2021-01-15 13:21 ` [PULL 08/30] audio: split pcm_ops function get_buffer_in Gerd Hoffmann
2021-01-15 13:21 ` [PULL 09/30] sdlaudio: add recording functions Gerd Hoffmann
2021-01-15 13:21 ` [PULL 10/30] audio: break generic buffer dependency on mixing-engine Gerd Hoffmann
2021-01-15 13:21 ` [PULL 11/30] sdlaudio: enable (in|out).mixing-engine=off Gerd Hoffmann
2021-01-15 13:21 ` [PULL 12/30] audio: remove remaining unused plive code Gerd Hoffmann
2021-01-15 13:21 ` Gerd Hoffmann [this message]
2021-01-15 13:21 ` [PULL 14/30] paaudio: wait for PA_STREAM_READY in qpa_write() Gerd Hoffmann
2021-01-15 13:21 ` [PULL 15/30] paaudio: wait until the playback stream is ready Gerd Hoffmann
2021-01-15 13:21 ` [PULL 16/30] paaudio: remove unneeded code Gerd Hoffmann
2021-01-15 13:21 ` [PULL 17/30] paaudio: comment bugs in functions qpa_init_* Gerd Hoffmann
2021-01-15 13:21 ` [PULL 18/30] paaudio: limit minreq to 75% of audio timer_rate Gerd Hoffmann
2021-01-15 13:21 ` [PULL 19/30] paaudio: send recorded data in smaller chunks Gerd Hoffmann
2021-01-15 13:21 ` [PULL 20/30] dsoundaudio: replace GetForegroundWindow() Gerd Hoffmann
2021-01-15 13:21 ` [PULL 21/30] dsoundaudio: rename dsound_open() Gerd Hoffmann
2021-01-15 13:21 ` [PULL 22/30] dsoundaudio: enable f32 audio sample format Gerd Hoffmann
2021-01-15 13:21 ` [PULL 23/30] dsoundaudio: fix log message Gerd Hoffmann
2021-01-15 13:21 ` [PULL 24/30] audio: Add braces for statements/fix braces' position Gerd Hoffmann
2021-01-15 13:21 ` [PULL 25/30] audio: Add spaces around operator/delete redundant spaces Gerd Hoffmann
2021-01-15 13:21 ` [PULL 26/30] audio: foo* bar" should be "foo *bar" Gerd Hoffmann
2021-01-15 13:21 ` [PULL 27/30] audio: Fix lines over 90 characters Gerd Hoffmann
2021-01-15 13:21 ` [PULL 28/30] audio: Don't use '%#' in format strings Gerd Hoffmann
2021-01-15 13:21 ` [PULL 29/30] audio: Suspect code indent for conditional statements Gerd Hoffmann
2021-01-15 13:21 ` [PULL 30/30] audio: space prohibited between function name and parenthesis'(' Gerd Hoffmann
2021-01-15 14:24 ` [PULL 00/30] Audio 20210115 patches no-reply
2021-01-16 12:56 ` Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210115132146.1443592-14-kraxel@redhat.com \
    --to=kraxel@redhat.com \
    --cc=armbru@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=vr_qemu@t-online.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.