qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Shreyansh Chouhan <chouhan.shreyansh2702@gmail.com>
To: kraxel@redhat.com, mst@redhat.com
Cc: Shreyansh Chouhan <chouhan.shreyansh2702@gmail.com>,
	qemu-devel@nongnu.org
Subject: [RFC PATCH 19/27] virtio-snd: Add callback for SWVoiceOut
Date: Thu, 29 Apr 2021 17:34:37 +0530	[thread overview]
Message-ID: <20210429120445.694420-20-chouhan.shreyansh2702@gmail.com> (raw)
In-Reply-To: <20210429120445.694420-1-chouhan.shreyansh2702@gmail.com>

Added the callback for writing audio using AUD_write. The callback uses
two helper functions for reading the buffers from the streams and
handling the buffers that were written. initialized the
SWVoiceOut using this callback.

Signed-off-by: Shreyansh Chouhan <chouhan.shreyansh2702@gmail.com>
---
 hw/audio/virtio-snd.c | 171 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 165 insertions(+), 6 deletions(-)

diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c
index d0ab19a04a..e5042caf9c 100644
--- a/hw/audio/virtio-snd.c
+++ b/hw/audio/virtio-snd.c
@@ -468,6 +468,165 @@ static int virtio_snd_pcm_get_nelems(virtio_snd_pcm_stream *st)
            + !!(st->buffer_bytes % st->period_bytes);
 }
 
+/*
+ * Get the size in bytes of the buffer that still has to be written.
+ *
+ * @st: virtio sound pcm stream
+ */
+static int virtio_snd_pcm_get_pending_bytes(virtio_snd_pcm_stream *st)
+{
+    int pending = st->r_pos - st->w_pos;
+    return pending < 0 ? pending + st->buffer_bytes : pending;
+}
+
+/*
+ * Get data from a stream of the virtio sound device.
+ *
+ * @st: VirtIOSound card stream
+ * @offset: Start reading from this offseta in the stream (in bytes)
+ * @buffer: Write to this buffer
+ * @size: The number of bytes to read
+ */
+static void virtio_snd_pcm_get_buf(virtio_snd_pcm_stream *st, uint32_t offset,
+                                      void *buffer, uint32_t size)
+{
+    int nelems = virtio_snd_pcm_get_nelems(st);
+    int i = 0;
+    while (offset > st->period_bytes) {
+        offset -= st->period_bytes;
+        i++;
+        i %= nelems;
+    }
+
+
+    /*
+     * If the size spans beyond the current virtqueue element, read everything
+     * from the current virtqueue element and move to the next element. Repeat
+     * until we have read the required size.
+     */
+    while (size) {
+        int remaining = iov_size(st->elems[i]->out_sg, st->elems[i]->out_num)
+                        - sizeof(virtio_snd_pcm_xfer) - offset;
+        int to_read = MIN(remaining, size), wpos = 0;
+        size_t sz;
+        sz = iov_to_buf(st->elems[i]->out_sg, st->elems[i]->out_num,
+                        sizeof(virtio_snd_pcm_xfer) + offset, buffer + wpos,
+                        to_read);
+
+        assert(sz == to_read);
+
+        offset = 0;
+        size -= to_read;
+        wpos += to_read;
+        i++;
+        i %= nelems;
+    }
+}
+
+/*
+ * Handle a buffer after it has been written by AUD_write.
+ * It writes the status for the I/O messages that have been completed and
+ * marks the tx virtqueue elmenets as used. It notifies the device
+ * about I/O completion.
+ *
+ * @st: VirtIOSound card stream
+ * @size: Size that was written by AUD_write
+ *        If size = 0, write for the last element failed
+ */
+static void virtio_snd_pcm_handle_buf_written(virtio_snd_pcm_stream *st,
+                                              uint32_t size)
+{
+    int offset = st->w_pos, i = 0;
+    int nelems = virtio_snd_pcm_get_nelems(st);
+
+    while (offset >= st->period_bytes) {
+        offset -= st->period_bytes;
+        i++;
+        i %= nelems;
+    }
+
+    virtio_snd_pcm_status status;
+    size_t sz;
+    if (!size) {
+        status.status = VIRTIO_SND_S_IO_ERR;
+        status.latency_bytes = 0;
+
+        sz = iov_from_buf(st->elems[i]->in_sg, st->elems[i]->in_num, 0,
+                          &status, sizeof(status));
+        assert(sz == sizeof(virtio_snd_pcm_status));
+
+        int push_size = iov_size(st->elems[i]->out_sg, st->elems[i]->out_num)
+                        + sizeof(virtio_snd_pcm_status);
+
+        virtqueue_push(st->s->tx_vq, st->elems[i], push_size);
+        return;
+    }
+
+    status.status = VIRTIO_SND_S_OK;
+    status.latency_bytes = 0;
+
+    /*
+     * If the written size spans beyond current element, update the status for
+     * the current element, mark it as used and push it back on the tx
+     * virtqueue. Notify the device about the I/O completion. Repeat until
+     * the required bytes are handled.
+     */
+    while (size) {
+        int curr_elem_size = iov_size(st->elems[i]->out_sg, st->elems[i]->out_num)
+                             - sizeof(virtio_snd_pcm_xfer) - offset;
+        if (size >= curr_elem_size) {
+            sz = iov_from_buf(st->elems[i]->in_sg, st->elems[i]->in_num, 0,
+                              &status, sizeof(status));
+            assert(sz == sizeof(virtio_snd_pcm_status));
+
+            int push_size = sizeof(virtio_snd_pcm_xfer) + curr_elem_size
+                            + offset + sizeof(virtio_snd_pcm_status);
+
+            virtqueue_push(st->s->tx_vq, st->elems[i], push_size);
+            virtio_notify(VIRTIO_DEVICE(st->s), st->s->tx_vq);
+            g_free(st->elems[i]);
+            st->elems[i] = NULL;
+            size -= curr_elem_size;
+            virtio_snd_log("remains: %d\n", size);
+            st->w_pos += curr_elem_size;
+            st->w_pos %= st->buffer_bytes + 1;
+            i++;
+            i %= nelems;
+            offset = 0;
+        } else {
+            st->w_pos += size;
+            st->w_pos %= st->buffer_bytes + 1;
+            break;
+        }
+    }
+}
+
+/*
+ * Callback for AUD_open_out.
+ * Reads a buffer from the VirtIOSound card stream and writes it
+ * using AUD_write.
+ *
+ * @opaque: VirtIOSound card stream
+ * @free: Size in bytes that can be written via AUD_write
+ */
+static void virtio_snd_output_cb(void *opaque, int free)
+{
+    int to_play, pending;
+    virtio_snd_pcm_stream *st = opaque;
+
+    pending = virtio_snd_pcm_get_pending_bytes(st);
+    to_play = MIN(free, pending);
+
+    while (to_play) {
+        uint8_t *mixbuf = g_malloc0(to_play);
+        virtio_snd_pcm_get_buf(st, st->w_pos, mixbuf, to_play);
+        int wbytes = AUD_write(st->voice.out, mixbuf, to_play);
+        to_play -= wbytes;
+        virtio_snd_pcm_handle_buf_written(st, wbytes);
+        g_free(mixbuf);
+    }
+}
+
 /*
  * Prepares a VirtIOSound card stream.
  * Returns a virtio sound status (VIRTIO_SND_S_*).
@@ -523,12 +682,12 @@ static uint32_t virtio_snd_pcm_prepare_impl(VirtIOSound *s, uint32_t stream)
     virtio_snd_get_qemu_audsettings(&as, s->pcm_params[stream]);
 
     if (st->direction == VIRTIO_SND_D_OUTPUT) {
-        /* st->voice.out = AUD_open_out(&s->card,
-         *                              st->voice.out,
-         *                              "virtio_snd_card",
-         *                              st,
-         *                              virtio_snd_output_cb, &as);
-         */
+        st->voice.out = AUD_open_out(&s->card,
+                                     st->voice.out,
+                                     "virtio_snd_card",
+                                     st,
+                                     virtio_snd_output_cb, &as);
+
     } else {
         /* st->voice.in = AUD_open_in(&s->card,
          *                            st->voice.in,
-- 
2.25.1



  parent reply	other threads:[~2021-04-29 12:39 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-29 12:04 [RFC PATCH 00/27] Virtio sound card implementation Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 01/27] virtio-snd: Add virtio sound header file Shreyansh Chouhan
2021-04-30  9:34   ` Gerd Hoffmann
2021-04-29 12:04 ` [RFC PATCH 02/27] virtio-snd: Add jack control structures Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 03/27] virtio-snd: Add PCM " Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 04/27] virtio-snd: Add chmap " Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 05/27] virtio-snd: Add device implementation structures Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 06/27] virtio-snd: Add PCI wrapper code for VirtIOSound Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 07/27] virtio-snd: Add properties for class init Shreyansh Chouhan
2021-05-04 13:32   ` Laurent Vivier
2021-05-04 19:35     ` Shreyansh Chouhan
2021-05-04 20:30       ` Laurent Vivier
2021-05-04 21:24         ` Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 08/27] virtio-snd: Add code for get config function Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 09/27] virtio-snd: Add code for set " Shreyansh Chouhan
2021-04-30  9:55   ` Gerd Hoffmann
2021-04-29 12:04 ` [RFC PATCH 10/27] virtio-snd: Add code for the realize function Shreyansh Chouhan
     [not found]   ` <CANo3dkpB6Qn46mDGdGE4KTNqHpJkajNcnq_4BugNC5jd8r042Q@mail.gmail.com>
2021-07-22  4:52     ` Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 11/27] virtio-snd: Add macros for logging Shreyansh Chouhan
2021-04-30  9:59   ` Gerd Hoffmann
2021-04-29 12:04 ` [RFC PATCH 12/27] virtio-snd: Add control virtqueue handler Shreyansh Chouhan
2021-04-30 10:02   ` Gerd Hoffmann
2021-04-29 12:04 ` [RFC PATCH 13/27] virtio-snd: Add VIRTIO_SND_R_JACK_INFO handler Shreyansh Chouhan
2021-04-30 10:13   ` Gerd Hoffmann
2021-04-29 12:04 ` [RFC PATCH 14/27] virtio-snd: Add stub for VIRTIO_SND_R_JACK_REMAP handler Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 15/27] virtio-snd: Add VIRTIO_SND_R_PCM_INFO handler Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 16/27] virtio-snd: Add VIRITO_SND_R_PCM_SET_PARAMS handle Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 17/27] virtio-snd: Add VIRTIO_SND_R_PCM_PREPARE handler Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 18/27] virtio-snd: Add default configs to realize fn Shreyansh Chouhan
2021-04-29 12:04 ` Shreyansh Chouhan [this message]
2021-04-29 12:04 ` [RFC PATCH 20/27] virtio-snd: Add VIRITO_SND_R_PCM_START handler Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 21/27] virtio-snd: Add VIRTIO_SND_R_PCM_STOP handler Shreyansh Chouhan
2021-04-30 10:22   ` Gerd Hoffmann
2021-04-29 12:04 ` [RFC PATCH 22/27] virtio-snd: Add VIRTIO_SND_R_PCM_RELEASE handler Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 23/27] virtio-snd: Replaced goto with if else Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 24/27] virtio-snd: Add code to device unrealize function Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 25/27] virtio-snd: Add tx vq and handler Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 26/27] virtio-snd: Add event vq and a handler stub Shreyansh Chouhan
2021-04-29 12:04 ` [RFC PATCH 27/27] virtio-snd: Add rx vq and stub handler Shreyansh Chouhan
2021-04-29 12:48 ` [RFC PATCH 00/27] Virtio sound card implementation no-reply
2021-04-30 10:56 ` Gerd Hoffmann
2022-02-11 22:12 ` [RFC PATCH v2 00/25] Virtio Sound card Implementation Shreyansh Chouhan
2022-02-12 19:08   ` Laurent Vivier
2022-02-14 10:44     ` Gerd Hoffmann
2022-02-14 11:11       ` Laurent Vivier
2023-02-22 13:11   ` Stefano Garzarella
2022-02-11 22:12 ` [RFC PATCH 01/25] virtio-snd: Add virtio sound header file Shreyansh Chouhan
2022-02-14 10:37   ` Gerd Hoffmann
2022-02-11 22:12 ` [RFC PATCH 02/25] virtio-snd: Add jack control structures Shreyansh Chouhan
2022-02-11 22:12 ` [RFC PATCH 03/25] virtio-snd: Add PCM " Shreyansh Chouhan
2022-02-11 22:12 ` [RFC PATCH 04/25] virtio-snd: Add chmap " Shreyansh Chouhan
2022-02-11 22:12 ` [RFC PATCH 05/25] virtio-snd: Add device implementation structures Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 06/25] virtio-snd: Add PCI wrapper code for VirtIOSound Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 07/25] virtio-snd: Add properties for class init Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 08/25] virtio-snd: Add code for get config function Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 09/25] virtio-snd: Add code for the realize function Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 10/25] virtio-snd: Add macros for logging Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 11/25] virtio-snd: Add control virtqueue handler Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 12/25] virtio-snd: Add VIRTIO_SND_R_JACK_INFO handler Shreyansh Chouhan
2022-02-12 19:10   ` Laurent Vivier
2022-02-11 22:13 ` [RFC PATCH 13/25] virtio-snd: Add stub for VIRTIO_SND_R_JACK_REMAP handler Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 14/25] virtio-snd: Add VIRTIO_SND_R_PCM_INFO handler Shreyansh Chouhan
2022-02-12 19:20   ` Laurent Vivier
2022-02-11 22:13 ` [RFC PATCH 15/25] virtio-snd: Add VIRITO_SND_R_PCM_SET_PARAMS handle Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 16/25] virtio-snd: Add VIRTIO_SND_R_PCM_PREPARE handler Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 17/25] virtio-snd: Add default configs to realize fn Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 18/25] virtio-snd: Add callback for SWVoiceOut Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 19/25] virtio-snd: Add start/stop handler Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 20/25] virtio-snd: Add VIRTIO_SND_R_PCM_RELEASE handler Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 21/25] virtio-snd: Replaced goto with if else Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 22/25] virtio-snd: Add code to device unrealize function Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 23/25] virtio-snd: Add xfer handler Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 24/25] virtio-snd: Add event vq and a handler stub Shreyansh Chouhan
2022-02-11 22:13 ` [RFC PATCH 25/25] virtio-snd: Replaced AUD_log with tracepoints Shreyansh Chouhan

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=20210429120445.694420-20-chouhan.shreyansh2702@gmail.com \
    --to=chouhan.shreyansh2702@gmail.com \
    --cc=kraxel@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).