From: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
To: qemu-devel@nongnu.org
Cc: "Emmanouil Pitsidianakis" <manos.pitsidianakis@linaro.org>,
"Igor Skalkin" <Igor.Skalkin@opensynergy.com>,
"Anton Yakovlev" <Anton.Yakovlev@opensynergy.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Gerd Hoffmann" <kraxel@redhat.com>,
"Michael S. Tsirkin" <mst@redhat.com>,
"Marcel Apfelbaum" <marcel.apfelbaum@gmail.com>,
"Daniel P. Berrangé" <berrange@redhat.com>,
"Eduardo Habkost" <eduardo@habkost.net>,
"Marc-André Lureau" <marcandre.lureau@redhat.com>,
"Volker Rümelin" <vr_qemu@t-online.de>,
"Kővágó, Zoltán" <DirtY.iCE.hu@gmail.com>,
"Alex Bennee" <alex.bennee@linaro.org>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>
Subject: [PATCH v4 00/12] Add VIRTIO sound card
Date: Thu, 20 Jul 2023 15:57:01 +0300 [thread overview]
Message-ID: <cover.1689857559.git.manos.pitsidianakis@linaro.org> (raw)
This patch series adds an audio device implementing the recent virtio
sound spec (1.2) and a corresponding PCI wrapper device.
Main differences with v3 patch [^v3]
<cover.1689692765.git.manos.pitsidianakis@linaro.org>:
- Addressed review style comments.
- Split patches for easier review.
[^v3]:
https://lore.kernel.org/qemu-devel/cover.1689692765.git.manos.pitsidianakis@linaro.org/
Emmanouil Pitsidianakis (12):
Add virtio-sound device stub
Add virtio-sound-pci device
virtio-sound: handle control messages and streams
virtio-sound: set PCM stream parameters
virtio-sound: prepare PCM streams
virtio-sound: handle VIRTIO_SND_R_PCM_INFO request
virtio-sound: handle VIRTIO_SND_R_PCM_{START,STOP}
virtio-sound: handle VIRTIO_SND_PCM_SET_PARAMS
virtio-sound: handle VIRTIO_SND_R_PCM_PREPARE
virtio-sound: handle VIRTIO_SND_PCM_RELEASE
virtio-sound: implement audio output (TX)
virtio-sound: implement audio capture (RX)
MAINTAINERS | 6 +
hw/virtio/Kconfig | 5 +
hw/virtio/meson.build | 2 +
hw/virtio/trace-events | 20 +
hw/virtio/virtio-snd-pci.c | 91 +++
hw/virtio/virtio-snd.c | 1298 ++++++++++++++++++++++++++++++++
include/hw/pci/pci.h | 1 +
include/hw/virtio/virtio-snd.h | 157 ++++
softmmu/qdev-monitor.c | 1 +
9 files changed, 1581 insertions(+)
create mode 100644 hw/virtio/virtio-snd-pci.c
create mode 100644 hw/virtio/virtio-snd.c
create mode 100644 include/hw/virtio/virtio-snd.h
Range-diff against v3:
1: 93c763e275 < -: ---------- Add virtio-sound device
-: ---------- > 1: ae372de565 Add virtio-sound device stub
2: 36373d92fa ! 2: 5cde5472ea Add virtio-sound-pci device
@@
## Metadata ##
-Author: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+Author: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
## Commit message ##
Add virtio-sound-pci device
This patch adds a PCI wrapper device for the virtio-sound device.
+ It is necessary to instantiate a virtio-snd device in a guest.
+ All sound logic will be added to the virtio-snd device in the following
+ commits.
- To test this, you'll need a >=5.13 kernel compiled with
- CONFIG_SND_VIRTIO=y, which at the time of writing most distros have off
- by default.
+ To add this device with a guest, you'll need a >=5.13 kernel compiled
+ with CONFIG_SND_VIRTIO=y, which at the time of writing most distros have
+ off by default.
Use with following flags in the invocation:
@@ Commit message
Pulseaudio:
-audio driver=pa,model=virtio-sound
+ or
+ -audio driver=pa,model=virtio-sound,server=/run/user/1000/pulse/native
sdl:
-audio driver=sdl,model=virtio-sound
coreaudio (macos/darwin):
-audio driver=coreaudio,model=virtio-sound
etc.
- You can use speaker-test from alsa-tools to play noise, sines, or
- WAV files.
-
Signed-off-by: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
## hw/virtio/meson.build ##
@@ hw/virtio/virtio-snd-pci.c (new)
+{
+ VirtIOSoundPCI *dev = VIRTIO_SOUND_PCI(vpci_dev);
+ DeviceState *vdev = DEVICE(&dev->vdev);
-+ VirtIOSound *vsnd = VIRTIO_SND(&dev->vdev);
-+
-+ /*
-+ * According to spec, non-legacy virtio PCI devices are always little
-+ * endian
-+ */
-+ vsnd->virtio_access_is_big_endian = false;
-+
+
+ qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus), errp);
-+
+ qdev_prop_set_string(vdev, "audiodev", audiodev_id);
-+
+ object_property_set_bool(OBJECT(vdev), "realized", true, errp);
+}
+
-: ---------- > 3: dc65cac2f4 virtio-sound: handle control messages and streams
-: ---------- > 4: bbd1799fc9 virtio-sound: set PCM stream parameters
-: ---------- > 5: 68a13c4385 virtio-sound: prepare PCM streams
-: ---------- > 6: f267d41957 virtio-sound: handle VIRTIO_SND_R_PCM_INFO request
-: ---------- > 7: 5939a6161e virtio-sound: handle VIRTIO_SND_R_PCM_{START,STOP}
-: ---------- > 8: 8f78d3a132 virtio-sound: handle VIRTIO_SND_PCM_SET_PARAMS
-: ---------- > 9: d2b3854084 virtio-sound: handle VIRTIO_SND_R_PCM_PREPARE
-: ---------- > 10: 4e14b2d129 virtio-sound: handle VIRTIO_SND_PCM_RELEASE
-: ---------- > 11: a6a0f07c7a virtio-sound: implement audio output (TX)
3: 8d432c85a2 ! 12: 1abb69dd05 Implement audio capture in virtio-snd device
@@
## Metadata ##
-Author: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
+Author: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
## Commit message ##
- Implement audio capture in virtio-snd device
+ virtio-sound: implement audio capture (RX)
+
+ To perform audio capture we duplicate the TX logic of the previous
+ commit with the following difference: we receive data from the QEMU
+ audio backend and write it in the virt queue IO buffers the guest sends
+ to QEMU. When they are full (i.e. they have `period_bytes` amount of
+ data) or when recording stops in QEMU's audio backend, the buffer is
+ returned to the guest by notifying it.
Signed-off-by: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
## hw/virtio/trace-events ##
-@@ hw/virtio/trace-events: virtio_snd_handle_pcm_set_params(int stream) "VIRTIO_SND_PCM_SET_PARAMS called f
- virtio_snd_handle_pcm_start_stop(const char *code, int stream) "%s called for stream %d"
- virtio_snd_handle_pcm_release(int stream) "VIRTIO_SND_PCM_RELEASE called for stream %d"
+@@ hw/virtio/trace-events: virtio_snd_handle_code(uint32_t val, const char *code) "ctrl code msg val = %"PR
virtio_snd_handle_chmap_info(void) "VIRTIO_SND_CHMAP_INFO called"
+ virtio_snd_handle_event(void) "event queue callback called"
+ virtio_snd_pcm_stream_flush(uint32_t stream) "flushing stream %"PRIu32
-virtio_snd_handle_xfer(void) "tx/rx queue callback called"
+virtio_snd_handle_tx_xfer(void) "tx queue callback called"
-+virtio_snd_handle_rx_xfer(void) "rx queue callback called"
- virtio_snd_handle_event(void) "event queue callback called"
- virtio_snd_realize(void *snd) "snd %p: realize"
- virtio_snd_unrealize(void *snd) "snd %p: unrealize"
++virtio_snd_handle_rx_xfer(void) "tx queue callback called"
## hw/virtio/virtio-snd.c ##
@@
- #define VIRTIO_SOUND_VM_VERSION 1
+ #define VIRTIO_SOUND_VM_VERSION 1
#define VIRTIO_SOUND_JACK_DEFAULT 0
-#define VIRTIO_SOUND_STREAM_DEFAULT 1
+#define VIRTIO_SOUND_STREAM_DEFAULT 2
#define VIRTIO_SOUND_CHMAP_DEFAULT 0
-
#define VIRTIO_SOUND_HDA_FN_NID 0
-@@ hw/virtio/virtio-snd.c: virtio_snd_set_config(VirtIODevice *vdev, const uint8_t *config)
- }
+ static void virtio_snd_pcm_out_cb(void *data, int available);
static void virtio_snd_process_cmdq(VirtIOSound *s);
-static void virtio_snd_pcm_flush(VirtIOSoundPCMStream *stream);
+-static uint32_t
+-virtio_snd_pcm_read_write(VirtIOSoundPCMStream *stream,
+- VirtQueue *vq,
+- VirtQueueElement *element,
+- bool read);
+static void virtio_snd_pcm_out_flush(VirtIOSoundPCMStream *stream);
+static void virtio_snd_pcm_in_flush(VirtIOSoundPCMStream *stream);
- static void virtio_snd_pcm_out_cb(void *data, int available);
--static uint32_t virtio_snd_pcm_read_write(VirtIOSoundPCMStream *stream,
+static void virtio_snd_pcm_in_cb(void *data, int available);
+static uint32_t virtio_snd_pcm_write(VirtIOSoundPCMStream *stream,
- VirtQueue *vq,
-- VirtQueueElement *element,
-- bool read);
-+ VirtQueueElement *element);
++ VirtQueue *vq,
++ VirtQueueElement *element);
+static uint32_t virtio_snd_pcm_read(VirtIOSoundPCMStream *stream,
-+ VirtQueue *vq,
-+ VirtQueueElement *element);
++ VirtQueue *vq,
++ VirtQueueElement *element);
- /*
- * Get a specific stream from the virtio sound card device.
+ static uint32_t supported_formats = BIT(VIRTIO_SND_PCM_FMT_S8)
+ | BIT(VIRTIO_SND_PCM_FMT_U8)
@@ hw/virtio/virtio-snd.c: static uint32_t virtio_snd_pcm_prepare_impl(VirtIOSound *s, uint32_t stream_id)
+ virtio_snd_pcm_out_cb,
&as);
-
} else {
- qemu_log_mask(LOG_UNIMP, "virtio_snd: input/capture is unimplemented.");
-- /*
-- * stream->voice.in = AUD_open_in(&s->card,
-- * stream->voice.in,
-- * "virtio_snd_card",
-- * stream,
-- * virtio_snd_input_cb,
-- * &as);
-- */
+ stream->voice.in = AUD_open_in(&s->card,
+ stream->voice.in,
+ "virtio_snd_card",
@@ hw/virtio/virtio-snd.c: static void virtio_snd_handle_pcm_start_stop(VirtIOSound
+ AUD_set_active_in(stream->voice.in, start);
}
} else {
- error_report("Invalid stream id: %d", req.stream_id);
+ error_report("Invalid stream id: %"PRIu32, req.stream_id);
@@ hw/virtio/virtio-snd.c: static uint32_t virtio_snd_pcm_release_impl(VirtIOSoundPCMStream *stream,
*/
virtio_snd_process_cmdq(stream->s);
@@ hw/virtio/virtio-snd.c: static void virtio_snd_handle_event(VirtIODevice *vdev,
* @vdev: VirtIOSound device
* @vq: tx virtqueue
*/
--static void virtio_snd_handle_xfer(VirtIODevice *vdev, VirtQueue *vq)
+-static void virtio_snd_handle_tx(VirtIODevice *vdev, VirtQueue *vq)
+static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOSound *s = VIRTIO_SND(vdev);
VirtIOSoundPCMStream *stream = NULL;
-@@ hw/virtio/virtio-snd.c: static void virtio_snd_handle_xfer(VirtIODevice *vdev, VirtQueue *vq)
+@@ hw/virtio/virtio-snd.c: static void virtio_snd_handle_tx(VirtIODevice *vdev, VirtQueue *vq)
virtio_snd_pcm_xfer hdr;
virtio_snd_pcm_status resp = { 0 };
@@ hw/virtio/virtio-snd.c: static void virtio_snd_handle_xfer(VirtIODevice *vdev, V
for (;;) {
elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
-@@ hw/virtio/virtio-snd.c: static void virtio_snd_handle_xfer(VirtIODevice *vdev, VirtQueue *vq)
+@@ hw/virtio/virtio-snd.c: static void virtio_snd_handle_tx(VirtIODevice *vdev, VirtQueue *vq)
goto tx_err;
}
@@ hw/virtio/virtio-snd.c: static void virtio_snd_handle_xfer(VirtIODevice *vdev, V
resp.status = VIRTIO_SND_S_OK;
iov_from_buf(elem->in_sg,
@@ hw/virtio/virtio-snd.c: tx_err:
- virtio_notify(VIRTIO_DEVICE(s), vq);
}
-+/*
+ /*
+- * Stub buffer virtqueue handler.
+ * The rx virtqueue handler. Makes the buffers available to their respective
+ * streams for consumption.
-+ *
-+ * @vdev: VirtIOSound device
+ *
+ * @vdev: VirtIOSound device
+- * @vq: virtqueue
+ * @vq: tx virtqueue
-+ */
+ */
+-static void virtio_snd_handle_xfer(VirtIODevice *vdev, VirtQueue *vq) {}
+static void virtio_snd_handle_rx_xfer(VirtIODevice *vdev, VirtQueue *vq)
+{
+ VirtIOSound *s = VIRTIO_SND(vdev);
@@ hw/virtio/virtio-snd.c: tx_err:
+ */
+ virtio_notify(VIRTIO_DEVICE(s), vq);
+}
-+
-+
+
static uint64_t get_features(VirtIODevice *vdev, uint64_t features,
Error **errp)
- {
@@ hw/virtio/virtio-snd.c: static void virtio_snd_realize(DeviceState *dev, Error **errp)
virtio_snd_common_realize(dev,
virtio_snd_handle_ctrl,
virtio_snd_handle_event,
-- virtio_snd_handle_xfer,
+- virtio_snd_handle_tx,
- virtio_snd_handle_xfer,
+ virtio_snd_handle_tx_xfer,
+ virtio_snd_handle_rx_xfer,
@@ hw/virtio/virtio-snd.c: static void virtio_snd_pcm_out_cb(void *data, int availa
- VirtIOSoundPCMBlock *next;
+ uint32_t sz;
+ virtio_snd_pcm_status resp = { 0 };
-+ int size;
++ size_t size;
WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
- QSIMPLEQ_FOREACH_SAFE(block, &stream->queue, entry, next) {
@@ hw/virtio/virtio-snd.c: static void virtio_snd_pcm_out_cb(void *data, int availa
+ MIN(stream->period_bytes - block->offset, available));
+ block->offset += size;
+ block->size += size;
-+ if (size == 0 || block->size == stream->period_bytes) {
++ if (size == 0 || block->size >= stream->period_bytes) {
+ resp.status = VIRTIO_SND_S_OK;
+ sz = iov_from_buf(block->elem->in_sg,
+ block->elem->in_num,
@@ hw/virtio/virtio-snd.c: static void virtio_snd_pcm_out_cb(void *data, int availa
+ block->elem->in_num,
+ sz,
+ &block->data,
-+ block->size);
++ MIN(stream->period_bytes, block->size));
+ }
+ virtqueue_push(block->vq,
+ block->elem,
base-commit: 2c27fdc7a626408ee2cf30d791aa0b63027c7404
--
2.39.2
next reply other threads:[~2023-07-20 12:58 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-20 12:57 Emmanouil Pitsidianakis [this message]
2023-07-20 12:57 ` [PATCH v4 01/12] Add virtio-sound device stub Emmanouil Pitsidianakis
2023-07-25 14:22 ` Marc-André Lureau
2023-07-25 14:31 ` Marc-André Lureau
2023-07-25 14:50 ` Michael S. Tsirkin
2023-07-20 12:57 ` [PATCH v4 02/12] Add virtio-sound-pci device Emmanouil Pitsidianakis
2023-07-20 12:57 ` [PATCH v4 03/12] virtio-sound: handle control messages and streams Emmanouil Pitsidianakis
2023-07-20 12:57 ` [PATCH v4 04/12] virtio-sound: set PCM stream parameters Emmanouil Pitsidianakis
2023-07-20 12:57 ` [PATCH v4 05/12] virtio-sound: prepare PCM streams Emmanouil Pitsidianakis
2023-07-25 13:38 ` Marc-André Lureau
2023-07-20 12:57 ` [PATCH v4 06/12] virtio-sound: handle VIRTIO_SND_R_PCM_INFO request Emmanouil Pitsidianakis
2023-07-25 14:29 ` Marc-André Lureau
2023-07-25 14:46 ` Michael S. Tsirkin
2023-07-25 14:54 ` Marc-André Lureau
2023-07-25 16:15 ` Michael S. Tsirkin
2023-07-25 14:30 ` Marc-André Lureau
2023-07-20 12:57 ` [PATCH v4 07/12] virtio-sound: handle VIRTIO_SND_R_PCM_{START,STOP} Emmanouil Pitsidianakis
2023-07-20 12:57 ` [PATCH v4 08/12] virtio-sound: handle VIRTIO_SND_PCM_SET_PARAMS Emmanouil Pitsidianakis
2023-07-20 12:57 ` [PATCH v4 09/12] virtio-sound: handle VIRTIO_SND_R_PCM_PREPARE Emmanouil Pitsidianakis
2023-07-20 12:57 ` [PATCH v4 10/12] virtio-sound: handle VIRTIO_SND_PCM_RELEASE Emmanouil Pitsidianakis
2023-07-20 12:57 ` [PATCH v4 11/12] virtio-sound: implement audio output (TX) Emmanouil Pitsidianakis
2023-07-20 12:57 ` [PATCH v4 12/12] virtio-sound: implement audio capture (RX) Emmanouil Pitsidianakis
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=cover.1689857559.git.manos.pitsidianakis@linaro.org \
--to=manos.pitsidianakis@linaro.org \
--cc=Anton.Yakovlev@opensynergy.com \
--cc=DirtY.iCE.hu@gmail.com \
--cc=Igor.Skalkin@opensynergy.com \
--cc=alex.bennee@linaro.org \
--cc=berrange@redhat.com \
--cc=eduardo@habkost.net \
--cc=kraxel@redhat.com \
--cc=marcandre.lureau@redhat.com \
--cc=marcel.apfelbaum@gmail.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=philmd@linaro.org \
--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 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).