From: Shreyansh Chouhan <chouhan.shreyansh2702@gmail.com>
To: kraxel@redhat.com, mst@redhat.com, laurent@vivier.eu
Cc: Shreyansh Chouhan <chouhan.shreyansh2702@gmail.com>,
qemu-devel@nongnu.org
Subject: [RFC PATCH 18/25] virtio-snd: Add callback for SWVoiceOut
Date: Sat, 12 Feb 2022 03:43:12 +0530 [thread overview]
Message-ID: <20220211221319.193404-19-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 | 254 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 248 insertions(+), 6 deletions(-)
diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c
index 5ed8e524a6..b74c9e4a1f 100644
--- a/hw/audio/virtio-snd.c
+++ b/hw/audio/virtio-snd.c
@@ -476,6 +476,248 @@ static int virtio_snd_pcm_get_nelems(virtio_snd_pcm_stream *st)
+ !!(st->buffer_bytes % st->period_bytes);
}
+static uint32_t virtio_snd_pcm_get_buf_pos(virtio_snd_pcm_stream *st,
+ uint32_t dir)
+{
+ return (dir == VIRTIO_SND_D_OUTPUT) ? st->w_pos : st->r_pos;
+}
+
+static uint32_t virtio_snd_pcm_get_curr_elem(virtio_snd_pcm_stream *st,
+ uint32_t dir)
+{
+ uint32_t pos;
+ int nelems;
+
+ nelems = virtio_snd_pcm_get_nelems(st);
+ pos = virtio_snd_pcm_get_buf_pos(st, dir);
+
+ return (pos / st->period_bytes) % nelems;
+}
+
+static uint32_t virtio_snd_pcm_get_curr_elem_cap(virtio_snd_pcm_stream *st,
+ uint32_t dir)
+{
+ uint32_t cap_bytes;
+ int i;
+
+ i = virtio_snd_pcm_get_curr_elem(st, dir);
+
+ if (dir == VIRTIO_SND_D_OUTPUT)
+ cap_bytes = iov_size(st->elems[i]->out_sg, st->elems[i]->out_num)
+ - sizeof(virtio_snd_pcm_xfer);
+ else
+ cap_bytes = iov_size(st->elems[i]->in_sg, st->elems[i]->in_num)
+ - sizeof(virtio_snd_pcm_status);
+
+ return cap_bytes;
+}
+
+static uint32_t virtio_snd_pcm_get_curr_elem_used(virtio_snd_pcm_stream *st,
+ uint32_t dir)
+{
+ uint32_t pos;
+
+ pos = virtio_snd_pcm_get_buf_pos(st, dir);
+
+ return pos % st->period_bytes;
+}
+
+static uint32_t virtio_snd_pcm_get_curr_elem_free(virtio_snd_pcm_stream *st,
+ uint32_t dir)
+{
+ uint32_t free_bytes, used;
+
+ used = virtio_snd_pcm_get_curr_elem_used(st, dir);
+ free_bytes = virtio_snd_pcm_get_curr_elem_cap(st, dir) - used;
+
+ return free_bytes;
+}
+
+/*
+ * Get the size in bytes of the buffer that still has to be written.
+ *
+ * @st: virtio sound pcm stream
+ */
+static uint32_t virtio_snd_pcm_get_pending_bytes(virtio_snd_pcm_stream *st)
+{
+ return (st->direction == VIRTIO_SND_D_OUTPUT) ?
+ st->r_pos - st->w_pos :
+ st->w_pos - st->r_pos;
+}
+
+static uint32_t virtio_snd_pcm_get_buf_to_proc(virtio_snd_pcm_stream *st,
+ size_t size)
+{
+ uint32_t to_proc, elem_free;
+
+ elem_free = virtio_snd_pcm_get_curr_elem_free(st, st->direction);
+ to_proc = MIN(elem_free, size);
+
+ return to_proc;
+}
+
+static void virtio_snd_pcm_update_buf_pos(virtio_snd_pcm_stream *st, uint32_t dir,
+ uint32_t size)
+{
+ if (dir == VIRTIO_SND_D_OUTPUT)
+ st->w_pos += size;
+ else
+ st->r_pos += size;
+}
+
+/*
+ * Get data from a stream of the virtio sound device. Only reads upto the
+ * end of the current virtqueue element. Returns the number of bytes read.
+ *
+ * @buffer: Write to this buffer
+ * @size: The number of bytes to read
+ * @st: VirtIOSound card stream
+ * @offset: Start reading from this offseta in the stream (in bytes)
+ */
+static size_t virtio_snd_pcm_buf_read(void *buf, size_t to_read,
+ virtio_snd_pcm_stream *st)
+{
+ size_t sz;
+ int i, used;
+
+ used = virtio_snd_pcm_get_curr_elem_used(st, st->direction);
+ i = virtio_snd_pcm_get_curr_elem(st, st->direction);
+
+ sz = iov_to_buf(st->elems[i]->out_sg, st->elems[i]->out_num,
+ sizeof(virtio_snd_pcm_xfer) + used, buf, to_read);
+
+ assert(sz == to_read);
+ return sz;
+}
+
+/*
+ * Marks an element as used, pushes it to queue and notifies the device.
+ * Also frees the element
+ */
+static void virtio_snd_pcm_handle_elem_used(virtio_snd_pcm_stream *st)
+{
+ int elem_size, i;
+ size_t sz, offset;
+
+ virtio_snd_pcm_status status;
+ status.status = VIRTIO_SND_S_OK;
+ status.latency_bytes = 0;
+
+ i = virtio_snd_pcm_get_curr_elem(st, st->direction);
+ elem_size = iov_size(st->elems[i]->out_sg, st->elems[i]->out_num)
+ + iov_size(st->elems[i]->in_sg, st->elems[i]->in_num);
+ offset = iov_size(st->elems[i]->in_sg, st->elems[i]->in_num)
+ - sizeof(virtio_snd_pcm_status);
+
+ sz = iov_from_buf(st->elems[i]->in_sg, st->elems[i]->in_num, offset,
+ &status, sizeof(status));
+ assert(sz == sizeof(virtio_snd_pcm_status));
+
+ virtqueue_push(st->s->tx_vq, st->elems[i], elem_size);
+ virtio_notify(VIRTIO_DEVICE(st->s), st->s->tx_vq);
+
+ g_free(st->elems[i]);
+ st->elems[i] = NULL;
+}
+
+/*
+ * 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. Returns the number of bytes handled.
+ *
+ * @st: VirtIOSound card stream
+ * @size: Size that was written by AUD_write
+ * If size = 0, write for the last element failed
+ */
+static size_t virtio_snd_pcm_handle_used(virtio_snd_pcm_stream *st,
+ size_t size)
+{
+ if (size == 0)
+ // error
+ return 0;
+
+ size_t used, elem_buf_size;
+
+ used = virtio_snd_pcm_get_curr_elem_used(st, st->direction);
+ elem_buf_size = virtio_snd_pcm_get_curr_elem_cap(st, st->direction);
+
+ if (used + size == elem_buf_size)
+ virtio_snd_pcm_handle_elem_used(st);
+
+ virtio_snd_pcm_update_buf_pos(st, st->direction, size);
+
+ return size;
+}
+
+/*
+ * Writes upto the end of the current virtqueue element.
+ * Returns the numbre of bytes written.
+ *
+ * @st: Virtio sound card stream
+ * @size: Number of bytes to write to HWVoiceOut
+ */
+static size_t write_audio(virtio_snd_pcm_stream *st,
+ uint32_t size)
+{
+ size_t to_write, handled, written;
+ void *mixbuf;
+
+ to_write = virtio_snd_pcm_get_buf_to_proc(st, size);
+ mixbuf = g_malloc0(to_write);
+ to_write = virtio_snd_pcm_buf_read(mixbuf, to_write, st);
+ written = AUD_write(st->voice.out, mixbuf, to_write);
+ handled = virtio_snd_pcm_handle_used(st, written);
+ assert(handled == written);
+
+ g_free(mixbuf);
+ return written;
+}
+
+/*
+ * 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;
+ int written = 0;
+
+ pending = virtio_snd_pcm_get_pending_bytes(st);
+
+ if (!pending && st->flushing) {
+ st->flushing = false;
+
+ if (st->direction == VIRTIO_SND_D_OUTPUT)
+ AUD_set_active_out(st->voice.out, false);
+ else
+ AUD_set_active_in(st->voice.in, false);
+ return;
+ }
+
+ to_play = MIN(free, pending);
+
+ virtio_snd_log("to_play: %d, free: %d, pending: %d\n", to_play, free, pending);
+ while (to_play) {
+ int wbytes = write_audio(st, to_play);
+
+ if (!wbytes)
+ break;
+
+ to_play -= wbytes;
+ free -= wbytes;
+ written += wbytes;
+ pending -= wbytes;
+ }
+
+ virtio_snd_log("written: %d\n", written);
+}
+
/*
* Prepares a VirtIOSound card stream.
* Returns a virtio sound status (VIRTIO_SND_S_*).
@@ -537,12 +779,12 @@ static uint32_t virtio_snd_pcm_prepare_impl(VirtIOSound *s, uint32_t stream)
virtio_snd_get_qemu_audsettings(&as, params);
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.31.1
next prev parent reply other threads:[~2022-02-11 22:34 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 ` [RFC PATCH 19/27] virtio-snd: Add callback for SWVoiceOut Shreyansh Chouhan
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 ` Shreyansh Chouhan [this message]
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=20220211221319.193404-19-chouhan.shreyansh2702@gmail.com \
--to=chouhan.shreyansh2702@gmail.com \
--cc=kraxel@redhat.com \
--cc=laurent@vivier.eu \
--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).