mbox series

[v8,00/12] Add VIRTIO sound card

Message ID cover.1693252037.git.manos.pitsidianakis@linaro.org (mailing list archive)
Headers show
Series Add VIRTIO sound card | expand

Message

Manos Pitsidianakis Aug. 28, 2023, 7:54 p.m. UTC
This patch series adds an audio device implementing the recent virtio 
sound spec (1.2) and a corresponding PCI wrapper device.

v8 can be found online at:

https://gitlab.com/epilys/qemu/-/tree/virtio-snd-v8

Ref 69eb5f4fbae731f5fc05dea8a5f4b656e0de127f

Main differences with v7 patch series [^v7]
<cover.1692731646.git.manos.pitsidianakis@linaro.org>:

- Addressed [^v7] review comments.
  Functions that were called from more than one place for code re-use 
  are not created until they are actually needed.
- Fixed cases where block->offset was not respected in Playback

Previously:

[^v7]
https://lore.kernel.org/qemu-devel/cover.1692731646.git.manos.pitsidianakis@linaro.org/
[^v6]: 
https://lore.kernel.org/qemu-devel/cover.1692089917.git.manos.pitsidianakis@linaro.org/
[^v5]: 
https://lore.kernel.org/qemu-devel/cover.1690626150.git.manos.pitsidianakis@linaro.org/
[^v4]: 
https://lore.kernel.org/qemu-devel/cover.1689857559.git.manos.pitsidianakis@linaro.org/
[^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: handle VIRTIO_SND_R_PCM_INFO request
  virtio-sound: handle VIRTIO_SND_R_PCM_{START,STOP}
  virtio-sound: handle VIRTIO_SND_R_PCM_SET_PARAMS
  virtio-sound: handle VIRTIO_SND_R_PCM_PREPARE
  virtio-sound: handle VIRTIO_SND_R_PCM_RELEASE
  virtio-sound: implement audio output (TX)
  virtio-sound: implement audio capture (RX)
  docs/system: add basic virtio-snd documentation

 MAINTAINERS                        |    6 +
 docs/system/device-emulation.rst   |    1 +
 docs/system/devices/virtio-snd.rst |   49 ++
 hw/virtio/Kconfig                  |    5 +
 hw/virtio/meson.build              |    2 +
 hw/virtio/trace-events             |   20 +
 hw/virtio/virtio-snd-pci.c         |   97 +++
 hw/virtio/virtio-snd.c             | 1308 ++++++++++++++++++++++++++++
 include/hw/virtio/virtio-snd.h     |  155 ++++
 softmmu/qdev-monitor.c             |    1 +
 10 files changed, 1644 insertions(+)
 create mode 100644 docs/system/devices/virtio-snd.rst
 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 v7:
 1:  1a8ffb08d6 !  1:  238de1757e Add virtio-sound device stub
    @@ Commit message
         Add a new VIRTIO device for the virtio sound device id. Functionality
         will be added in the following commits.
     
    +    Based-on: https://github.com/OpenSynergy/qemu/commit/5a2f350eec5d157b90d9c7b40a8e603f4da92471
    +    Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
    +    Signed-off-by: Igor Skalkin <Igor.Skalkin@opensynergy.com>
    +    Signed-off-by: Anton Yakovlev <Anton.Yakovlev@opensynergy.com>
         Signed-off-by: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
     
      ## MAINTAINERS ##
    @@ hw/virtio/virtio-snd.c (new)
     +#include "qemu/osdep.h"
     +#include "qemu/iov.h"
     +#include "qemu/log.h"
    ++#include "qemu/error-report.h"
     +#include "include/qemu/lockable.h"
     +#include "sysemu/runstate.h"
     +#include "trace.h"
    @@ hw/virtio/virtio-snd.c (new)
     +    return features;
     +}
     +
    -+static void virtio_snd_common_realize(DeviceState *dev,
    -+                                      VirtIOHandleOutput ctrl,
    -+                                      VirtIOHandleOutput evt,
    -+                                      VirtIOHandleOutput txq,
    -+                                      VirtIOHandleOutput rxq,
    -+                                      Error **errp)
    ++static void
    ++virtio_snd_vm_state_change(void *opaque, bool running,
    ++                                       RunState state)
     +{
    -+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    ++    if (running) {
    ++        trace_virtio_snd_vm_state_running();
    ++    } else {
    ++        trace_virtio_snd_vm_state_stopped();
    ++    }
    ++}
    ++
    ++static void virtio_snd_realize(DeviceState *dev, Error **errp)
    ++{
    ++    ERRP_GUARD();
     +    VirtIOSound *vsnd = VIRTIO_SND(dev);
    ++    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    ++
    ++    vsnd->vmstate =
    ++        qemu_add_vm_change_state_handler(virtio_snd_vm_state_change, vsnd);
    ++
    ++    trace_virtio_snd_realize(vsnd);
     +
     +    virtio_init(vdev, VIRTIO_ID_SOUND, sizeof(virtio_snd_config));
     +    virtio_add_feature(&vsnd->features, VIRTIO_F_VERSION_1);
    @@ hw/virtio/virtio-snd.c (new)
     +
     +    AUD_register_card("virtio-sound", &vsnd->card);
     +
    -+    vsnd->queues[VIRTIO_SND_VQ_CONTROL] = virtio_add_queue(vdev, 64, ctrl);
    -+    vsnd->queues[VIRTIO_SND_VQ_EVENT] = virtio_add_queue(vdev, 64, evt);
    -+    vsnd->queues[VIRTIO_SND_VQ_TX] = virtio_add_queue(vdev, 64, txq);
    -+    vsnd->queues[VIRTIO_SND_VQ_RX] = virtio_add_queue(vdev, 64, rxq);
    -+}
    -+
    -+static void
    -+virtio_snd_vm_state_change(void *, bool running, RunState)
    -+{
    -+    if (running) {
    -+        trace_virtio_snd_vm_state_running();
    -+    } else {
    -+        trace_virtio_snd_vm_state_stopped();
    -+    }
    -+}
    -+
    -+static void virtio_snd_realize(DeviceState *dev, Error **errp)
    -+{
    -+    ERRP_GUARD();
    -+    VirtIOSound *vsnd = VIRTIO_SND(dev);
    -+
    -+    vsnd->vmstate =
    -+        qemu_add_vm_change_state_handler(virtio_snd_vm_state_change, vsnd);
    -+
    -+    trace_virtio_snd_realize(vsnd);
    -+
    -+    virtio_snd_common_realize(dev,
    -+                              virtio_snd_handle_queue,
    -+                              virtio_snd_handle_queue,
    -+                              virtio_snd_handle_queue,
    -+                              virtio_snd_handle_queue,
    -+                              errp);
    ++    vsnd->queues[VIRTIO_SND_VQ_CONTROL] =
    ++        virtio_add_queue(vdev, 64, virtio_snd_handle_queue);
    ++    vsnd->queues[VIRTIO_SND_VQ_EVENT] =
    ++        virtio_add_queue(vdev, 64, virtio_snd_handle_queue);
    ++    vsnd->queues[VIRTIO_SND_VQ_TX] =
    ++        virtio_add_queue(vdev, 64, virtio_snd_handle_queue);
    ++    vsnd->queues[VIRTIO_SND_VQ_RX] =
    ++        virtio_add_queue(vdev, 64, virtio_snd_handle_queue);
     +}
     +
     +static void virtio_snd_unrealize(DeviceState *dev)
 2:  a32cf5571b !  2:  8de966a86b Add virtio-sound-pci device
    @@ Commit message
           -audio driver=coreaudio,model=virtio
         etc.
     
    +    Based-on: https://github.com/OpenSynergy/qemu/commit/5a2f350eec5d157b90d9c7b40a8e603f4da92471
    +    Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
    +    Signed-off-by: Igor Skalkin <Igor.Skalkin@opensynergy.com>
    +    Signed-off-by: Anton Yakovlev <Anton.Yakovlev@opensynergy.com>
         Signed-off-by: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
     
      ## hw/virtio/meson.build ##
 3:  3f43057c32 !  3:  e3e57dd125 virtio-sound: handle control messages and streams
    @@ Commit message
     
         The handler is process_cmd() which replies with VIRTIO_SND_S_NOT_SUPP.
     
    +    Based-on: https://github.com/OpenSynergy/qemu/commit/5a2f350eec5d157b90d9c7b40a8e603f4da92471
    +    Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
    +    Signed-off-by: Igor Skalkin <Igor.Skalkin@opensynergy.com>
    +    Signed-off-by: Anton Yakovlev <Anton.Yakovlev@opensynergy.com>
         Signed-off-by: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
     
      ## hw/virtio/trace-events ##
    @@ hw/virtio/virtio-snd.c: virtio_snd_set_config(VirtIODevice *vdev, const uint8_t
      
      static uint64_t get_features(VirtIODevice *vdev, uint64_t features,
                                   Error **errp)
    -@@ hw/virtio/virtio-snd.c: static uint64_t get_features(VirtIODevice *vdev, uint64_t features,
    -     return features;
    +@@ hw/virtio/virtio-snd.c: virtio_snd_vm_state_change(void *opaque, bool running,
    +     }
      }
      
     +static void virtio_snd_set_pcm(VirtIOSound *snd)
    @@ hw/virtio/virtio-snd.c: static uint64_t get_features(VirtIODevice *vdev, uint64_
     +    snd->pcm = pcm;
     +}
     +
    - static void virtio_snd_common_realize(DeviceState *dev,
    -                                       VirtIOHandleOutput ctrl,
    -                                       VirtIOHandleOutput evt,
    -@@ hw/virtio/virtio-snd.c: static void virtio_snd_common_realize(DeviceState *dev,
    -     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    -     VirtIOSound *vsnd = VIRTIO_SND(dev);
    - 
    -+    virtio_snd_set_pcm(vsnd);
    -+
    -     virtio_init(vdev, VIRTIO_ID_SOUND, sizeof(virtio_snd_config));
    -     virtio_add_feature(&vsnd->features, VIRTIO_F_VERSION_1);
    - 
    -@@ hw/virtio/virtio-snd.c: static void virtio_snd_common_realize(DeviceState *dev,
    -     vsnd->queues[VIRTIO_SND_VQ_EVENT] = virtio_add_queue(vdev, 64, evt);
    -     vsnd->queues[VIRTIO_SND_VQ_TX] = virtio_add_queue(vdev, 64, txq);
    -     vsnd->queues[VIRTIO_SND_VQ_RX] = virtio_add_queue(vdev, 64, rxq);
    -+    qemu_mutex_init(&vsnd->cmdq_mutex);
    -+    QTAILQ_INIT(&vsnd->cmdq);
    - }
    - 
    - static void
    -@@ hw/virtio/virtio-snd.c: static void virtio_snd_realize(DeviceState *dev, Error **errp)
    + static void virtio_snd_realize(DeviceState *dev, Error **errp)
    + {
          ERRP_GUARD();
          VirtIOSound *vsnd = VIRTIO_SND(dev);
    +     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
      
     +    vsnd->pcm = NULL;
          vsnd->vmstate =
    @@ hw/virtio/virtio-snd.c: static void virtio_snd_realize(DeviceState *dev, Error *
      
          trace_virtio_snd_realize(vsnd);
      
    -     virtio_snd_common_realize(dev,
    --                              virtio_snd_handle_queue,
    --                              virtio_snd_handle_queue,
    --                              virtio_snd_handle_queue,
    --                              virtio_snd_handle_queue,
    -+                              virtio_snd_handle_ctrl,
    -+                              virtio_snd_handle_event,
    -+                              virtio_snd_handle_xfer,
    -+                              virtio_snd_handle_xfer,
    -                               errp);
    - }
    ++    virtio_snd_set_pcm(vsnd);
    ++
    +     virtio_init(vdev, VIRTIO_ID_SOUND, sizeof(virtio_snd_config));
    +     virtio_add_feature(&vsnd->features, VIRTIO_F_VERSION_1);
    + 
    +@@ hw/virtio/virtio-snd.c: static void virtio_snd_realize(DeviceState *dev, Error **errp)
    +     AUD_register_card("virtio-sound", &vsnd->card);
      
    +     vsnd->queues[VIRTIO_SND_VQ_CONTROL] =
    +-        virtio_add_queue(vdev, 64, virtio_snd_handle_queue);
    ++        virtio_add_queue(vdev, 64, virtio_snd_handle_ctrl);
    +     vsnd->queues[VIRTIO_SND_VQ_EVENT] =
    +-        virtio_add_queue(vdev, 64, virtio_snd_handle_queue);
    ++        virtio_add_queue(vdev, 64, virtio_snd_handle_event);
    +     vsnd->queues[VIRTIO_SND_VQ_TX] =
    +-        virtio_add_queue(vdev, 64, virtio_snd_handle_queue);
    ++        virtio_add_queue(vdev, 64, virtio_snd_handle_xfer);
    +     vsnd->queues[VIRTIO_SND_VQ_RX] =
    +-        virtio_add_queue(vdev, 64, virtio_snd_handle_queue);
    ++        virtio_add_queue(vdev, 64, virtio_snd_handle_xfer);
    ++    qemu_mutex_init(&vsnd->cmdq_mutex);
    ++    QTAILQ_INIT(&vsnd->cmdq);
    ++}
    ++
     +/*
     + * Close the stream and free its resources.
     + *
    @@ hw/virtio/virtio-snd.c: static void virtio_snd_realize(DeviceState *dev, Error *
     + */
     +static void virtio_snd_pcm_close(VirtIOSoundPCMStream *stream)
     +{
    -+}
    -+
    + }
    + 
      static void virtio_snd_unrealize(DeviceState *dev)
      {
          VirtIODevice *vdev = VIRTIO_DEVICE(dev);
 4:  34afff149a !  4:  6b3f8d8206 virtio-sound: set PCM stream parameters
    @@ Commit message
         PCM parameters describe the sound card parameters that the guest's
         kernel sees as an ALSA device.
     
    +    Based-on: https://github.com/OpenSynergy/qemu/commit/5a2f350eec5d157b90d9c7b40a8e603f4da92471
    +    Signed-off-by: Igor Skalkin <Igor.Skalkin@opensynergy.com>
    +    Signed-off-by: Anton Yakovlev <Anton.Yakovlev@opensynergy.com>
         Signed-off-by: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
     
      ## hw/virtio/virtio-snd.c ##
    @@ hw/virtio/virtio-snd.c: virtio_snd_set_config(VirtIODevice *vdev, const uint8_t
     + * @params: The PCM params as defined in the virtio specification
     + */
     +static
    -+uint32_t virtio_snd_pcm_set_params_impl(VirtIOSound *s,
    -+                                        virtio_snd_pcm_set_params *params)
    ++uint32_t virtio_snd_set_pcm_params(VirtIOSound *s,
    ++                                   virtio_snd_pcm_set_params *params)
     +{
     +    VirtIOSoundPCMParams *st_params;
     +    uint32_t stream_id = params->hdr.stream_id;
    @@ hw/virtio/virtio-snd.c: virtio_snd_set_config(VirtIODevice *vdev, const uint8_t
     + * @s: VirtIOSound device
     + * @stream_id: stream id
     + */
    -+static uint32_t virtio_snd_pcm_prepare_impl(VirtIOSound *s, uint32_t stream_id)
    ++static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id)
     +{
     +    audsettings as;
     +    VirtIOSoundPCMParams *params;
    @@ hw/virtio/virtio-snd.c: virtio_snd_set_config(VirtIODevice *vdev, const uint8_t
      /*
       * The actual processing done in virtio_snd_process_cmdq().
       *
    -@@ hw/virtio/virtio-snd.c: static void virtio_snd_common_realize(DeviceState *dev,
    - {
    -     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    +@@ hw/virtio/virtio-snd.c: static void virtio_snd_realize(DeviceState *dev, Error **errp)
    +     ERRP_GUARD();
          VirtIOSound *vsnd = VIRTIO_SND(dev);
    +     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
     +    virtio_snd_pcm_set_params default_params = { 0 };
     +    uint32_t status;
      
    -     virtio_snd_set_pcm(vsnd);
    - 
    -@@ hw/virtio/virtio-snd.c: static void virtio_snd_common_realize(DeviceState *dev,
    +     vsnd->pcm = NULL;
    +     vsnd->vmstate =
    +@@ hw/virtio/virtio-snd.c: static void virtio_snd_realize(DeviceState *dev, Error **errp)
      
          AUD_register_card("virtio-sound", &vsnd->card);
      
     +    /* set default params for all streams */
     +    default_params.features = 0;
    -+    default_params.buffer_bytes = 16384;
    -+    default_params.period_bytes = 4096;
    ++    default_params.buffer_bytes = 8192;
    ++    default_params.period_bytes = 2048;
     +    default_params.channels = 2;
     +    default_params.format = VIRTIO_SND_PCM_FMT_S16;
     +    default_params.rate = VIRTIO_SND_PCM_RATE_48000;
    -     vsnd->queues[VIRTIO_SND_VQ_CONTROL] = virtio_add_queue(vdev, 64, ctrl);
    -     vsnd->queues[VIRTIO_SND_VQ_EVENT] = virtio_add_queue(vdev, 64, evt);
    -     vsnd->queues[VIRTIO_SND_VQ_TX] = virtio_add_queue(vdev, 64, txq);
    -     vsnd->queues[VIRTIO_SND_VQ_RX] = virtio_add_queue(vdev, 64, rxq);
    +     vsnd->queues[VIRTIO_SND_VQ_CONTROL] =
    +         virtio_add_queue(vdev, 64, virtio_snd_handle_ctrl);
    +     vsnd->queues[VIRTIO_SND_VQ_EVENT] =
    +@@ hw/virtio/virtio-snd.c: static void virtio_snd_realize(DeviceState *dev, Error **errp)
    +         virtio_add_queue(vdev, 64, virtio_snd_handle_xfer);
          qemu_mutex_init(&vsnd->cmdq_mutex);
          QTAILQ_INIT(&vsnd->cmdq);
    -+
    +-}
    + 
    +-/*
    +- * Close the stream and free its resources.
    +- *
    +- * @stream: VirtIOSoundPCMStream *stream
    +- */
    +-static void virtio_snd_pcm_close(VirtIOSoundPCMStream *stream)
    +-{
     +    for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) {
     +        default_params.hdr.stream_id = i;
    -+        status = virtio_snd_pcm_set_params_impl(vsnd, &default_params);
    ++        status = virtio_snd_set_pcm_params(vsnd, &default_params);
     +        if (status != VIRTIO_SND_S_OK) {
     +            error_setg(errp,
     +                       "Can't initalize stream params, device responded with %s.",
     +                       print_code(status));
     +            return;
     +        }
    -+        status = virtio_snd_pcm_prepare_impl(vsnd, i);
    ++        status = virtio_snd_pcm_prepare(vsnd, i);
     +        if (status != VIRTIO_SND_S_OK) {
     +            error_setg(errp,
     +                       "Can't prepare streams, device responded with %s.",
    @@ hw/virtio/virtio-snd.c: static void virtio_snd_common_realize(DeviceState *dev,
     +    }
      }
      
    - static void
    -@@ hw/virtio/virtio-snd.c: static void virtio_snd_realize(DeviceState *dev, Error **errp)
    -                               errp);
    - }
    - 
    --/*
    -- * Close the stream and free its resources.
    -- *
    -- * @stream: VirtIOSoundPCMStream *stream
    -- */
    --static void virtio_snd_pcm_close(VirtIOSoundPCMStream *stream)
    --{
    --}
    --
      static void virtio_snd_unrealize(DeviceState *dev)
    - {
    -     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
     @@ hw/virtio/virtio-snd.c: static void virtio_snd_unrealize(DeviceState *dev)
              vsnd->pcm = NULL;
          }
 5:  0f433debd3 !  5:  974d88412d virtio-sound: handle VIRTIO_SND_R_PCM_INFO request
    @@ Commit message
         Respond to the VIRTIO_SND_R_PCM_INFO control request with the parameters
         of each requested PCM stream.
     
    +    Based-on: https://github.com/OpenSynergy/qemu/commit/5a2f350eec5d157b90d9c7b40a8e603f4da92471
    +    Signed-off-by: Igor Skalkin <Igor.Skalkin@opensynergy.com>
    +    Signed-off-by: Anton Yakovlev <Anton.Yakovlev@opensynergy.com>
         Signed-off-by: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
     
      ## hw/virtio/trace-events ##
 6:  70bb76519e !  6:  ff6f132004 virtio-sound: handle VIRTIO_SND_R_PCM_{START,STOP}
    @@ Commit message
         does nothing at the moment except for replying to it. Audio playback
         or capture will be started/stopped here in follow-up commits.
     
    +    Based-on: https://github.com/OpenSynergy/qemu/commit/5a2f350eec5d157b90d9c7b40a8e603f4da92471
    +    Signed-off-by: Igor Skalkin <Igor.Skalkin@opensynergy.com>
    +    Signed-off-by: Anton Yakovlev <Anton.Yakovlev@opensynergy.com>
         Signed-off-by: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
     
      ## hw/virtio/trace-events ##
    @@ hw/virtio/trace-events: virtio_snd_realize(void *snd) "snd %p: realize"
      virtio_snd_handle_event(void) "event queue callback called"
     
      ## hw/virtio/virtio-snd.c ##
    -@@ hw/virtio/virtio-snd.c: static uint32_t virtio_snd_pcm_prepare_impl(VirtIOSound *s, uint32_t stream_id)
    +@@ hw/virtio/virtio-snd.c: static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id)
          return VIRTIO_SND_S_OK;
      }
      
 7:  fb37cca76a !  7:  993e6af394 virtio-sound: handle VIRTIO_SND_PCM_SET_PARAMS
    @@ Metadata
     Author: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
     
      ## Commit message ##
    -    virtio-sound: handle VIRTIO_SND_PCM_SET_PARAMS
    +    virtio-sound: handle VIRTIO_SND_R_PCM_SET_PARAMS
     
         Handle the set parameters control request. It reconfigures a stream
         based on a guest's preference if the values are valid and supported.
     
    +    Based-on: https://github.com/OpenSynergy/qemu/commit/5a2f350eec5d157b90d9c7b40a8e603f4da92471
    +    Signed-off-by: Igor Skalkin <Igor.Skalkin@opensynergy.com>
    +    Signed-off-by: Anton Yakovlev <Anton.Yakovlev@opensynergy.com>
         Signed-off-by: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
     
      ## hw/virtio/trace-events ##
    @@ hw/virtio/trace-events: virtio_snd_vm_state_running(void) "vm state running"
      virtio_snd_handle_pcm_start_stop(const char *code, uint32_t stream) "%s called for stream %"PRIu32
     
      ## hw/virtio/virtio-snd.c ##
    -@@ hw/virtio/virtio-snd.c: uint32_t virtio_snd_pcm_set_params_impl(VirtIOSound *s,
    +@@ hw/virtio/virtio-snd.c: uint32_t virtio_snd_set_pcm_params(VirtIOSound *s,
          return VIRTIO_SND_S_OK;
      }
      
    @@ hw/virtio/virtio-snd.c: uint32_t virtio_snd_pcm_set_params_impl(VirtIOSound *s,
     +    }
     +
     +    trace_virtio_snd_handle_pcm_set_params(req.hdr.stream_id);
    -+    cmd->resp.code = virtio_snd_pcm_set_params_impl(s, &req);
    ++    cmd->resp.code = virtio_snd_set_pcm_params(s, &req);
     +}
     +
      /*
 8:  1e4bef953f !  8:  36ce5f4d63 virtio-sound: handle VIRTIO_SND_R_PCM_PREPARE
    @@ Commit message
         Handles the PCM prepare control request. It initializes a PCM stream
         when the guests asks for it.
     
    +    Based-on: https://github.com/OpenSynergy/qemu/commit/5a2f350eec5d157b90d9c7b40a8e603f4da92471
    +    Signed-off-by: Igor Skalkin <Igor.Skalkin@opensynergy.com>
    +    Signed-off-by: Anton Yakovlev <Anton.Yakovlev@opensynergy.com>
         Signed-off-by: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
     
      ## hw/virtio/virtio-snd.c ##
    -@@ hw/virtio/virtio-snd.c: static uint32_t virtio_snd_pcm_prepare_impl(VirtIOSound *s, uint32_t stream_id)
    +@@ hw/virtio/virtio-snd.c: static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id)
          return VIRTIO_SND_S_OK;
      }
      
    @@ hw/virtio/virtio-snd.c: static uint32_t virtio_snd_pcm_prepare_impl(VirtIOSound
     +                           sizeof(stream_id));
     +
     +    cmd->resp.code = sz == sizeof(uint32_t)
    -+                   ? virtio_snd_pcm_prepare_impl(s, stream_id)
    ++                   ? virtio_snd_pcm_prepare(s, stream_id)
     +                   : VIRTIO_SND_S_BAD_MSG;
     +}
     +
 9:  b1bc6e7c21 !  9:  30ad4bc665 virtio-sound: handle VIRTIO_SND_PCM_RELEASE
    @@ Metadata
     Author: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
     
      ## Commit message ##
    -    virtio-sound: handle VIRTIO_SND_PCM_RELEASE
    +    virtio-sound: handle VIRTIO_SND_R_PCM_RELEASE
     
         Handle the PCM release control request, which is necessary for flushing
         pending sound IO. No IO is handled yet so currently it only replies to
         the request.
     
    +    Based-on: https://github.com/OpenSynergy/qemu/commit/5a2f350eec5d157b90d9c7b40a8e603f4da92471
    +    Signed-off-by: Igor Skalkin <Igor.Skalkin@opensynergy.com>
    +    Signed-off-by: Anton Yakovlev <Anton.Yakovlev@opensynergy.com>
         Signed-off-by: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
     
      ## hw/virtio/trace-events ##
10:  fc27067092 ! 10:  c94a9c1e65 virtio-sound: implement audio output (TX)
    @@ Commit message
            releasing all IO messages back to the guest. This is how according to
            the spec the guest knows the release was successful.
     
    +    Based-on: https://github.com/OpenSynergy/qemu/commit/5a2f350eec5d157b90d9c7b40a8e603f4da92471
    +    Signed-off-by: Igor Skalkin <Igor.Skalkin@opensynergy.com>
    +    Signed-off-by: Anton Yakovlev <Anton.Yakovlev@opensynergy.com>
         Signed-off-by: Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org>
     
      ## hw/virtio/trace-events ##
    @@ hw/virtio/virtio-snd.c: static void virtio_snd_get_qemu_audsettings(audsettings
              qemu_mutex_destroy(&stream->queue_mutex);
              g_free(stream);
          }
    -@@ hw/virtio/virtio-snd.c: static uint32_t virtio_snd_pcm_prepare_impl(VirtIOSound *s, uint32_t stream_id)
    +@@ hw/virtio/virtio-snd.c: static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id)
          stream->positions[0] = VIRTIO_SND_CHMAP_FL;
          stream->positions[1] = VIRTIO_SND_CHMAP_FR;
      
    @@ hw/virtio/virtio-snd.c: static uint32_t virtio_snd_pcm_prepare_impl(VirtIOSound
          stream->as = as;
          stream->desired_as = stream->as;
          qemu_mutex_init(&stream->queue_mutex);
    +@@ hw/virtio/virtio-snd.c: static void virtio_snd_handle_pcm_start_stop(VirtIOSound *s,
    +                                              bool start)
    + {
    +     VirtIOSoundPCMStream *stream;
    ++    VirtIOSoundPCMBlock *block, *next;
    +     virtio_snd_pcm_hdr req;
    +     size_t sz = iov_to_buf(cmd->elem->out_sg,
    +                            cmd->elem->out_num,
     @@ hw/virtio/virtio-snd.c: static void virtio_snd_handle_pcm_start_stop(VirtIOSound *s,
                  "VIRTIO_SND_R_PCM_STOP", req.stream_id);
      
    @@ hw/virtio/virtio-snd.c: static void virtio_snd_handle_pcm_start_stop(VirtIOSound
     +        if (stream->direction == VIRTIO_SND_D_OUTPUT) {
     +            AUD_set_active_out(stream->voice.out, start);
     +        }
    ++        /* remove previous buffers. */
    ++        WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
    ++            QSIMPLEQ_FOREACH_SAFE(block, &stream->queue, entry, next) {
    ++                virtqueue_push(block->vq,
    ++                               block->elem,
    ++                               sizeof(block->elem));
    ++                virtio_notify(VIRTIO_DEVICE(stream->s), block->vq);
    ++                QSIMPLEQ_REMOVE_HEAD(&stream->queue, entry);
    ++                g_free(block);
    ++            }
    ++        }
     +    } else {
              error_report("Invalid stream id: %"PRIu32, req.stream_id);
              cmd->resp.code = VIRTIO_SND_S_BAD_MSG;
    @@ hw/virtio/virtio-snd.c: static void virtio_snd_handle_event(VirtIODevice *vdev,
       * Stub buffer virtqueue handler.
       *
     @@ 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,
    -                               errp);
    +     vsnd->queues[VIRTIO_SND_VQ_EVENT] =
    +         virtio_add_queue(vdev, 64, virtio_snd_handle_event);
    +     vsnd->queues[VIRTIO_SND_VQ_TX] =
    +-        virtio_add_queue(vdev, 64, virtio_snd_handle_xfer);
    ++        virtio_add_queue(vdev, 64, virtio_snd_handle_tx);
    +     vsnd->queues[VIRTIO_SND_VQ_RX] =
    +         virtio_add_queue(vdev, 64, virtio_snd_handle_xfer);
    +     qemu_mutex_init(&vsnd->cmdq_mutex);
    +@@ hw/virtio/virtio-snd.c: static void virtio_snd_realize(DeviceState *dev, Error **errp)
    +     }
      }
      
     +/*
    @@ hw/virtio/virtio-snd.c: static void virtio_snd_realize(DeviceState *dev, Error *
     +
     +    WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
     +        QSIMPLEQ_FOREACH_SAFE(block, &stream->queue, entry, next) {
    -+            AUD_write(stream->voice.out, block->data, block->size);
    ++            AUD_write(stream->voice.out, block->data + block->offset, block->size);
     +            virtqueue_push(block->vq, block->elem, sizeof(block->elem));
     +            virtio_notify(VIRTIO_DEVICE(stream->s), block->vq);
     +            QSIMPLEQ_REMOVE(&stream->queue, block, VirtIOSoundPCMBlock, entry);
11:  770e8b2fe7 ! 11:  9a85da0dde virtio-sound: implement audio capture (RX)
    @@ hw/virtio/virtio-snd.c: static void virtio_snd_pcm_close(VirtIOSoundPCMStream *s
              }
              qemu_mutex_destroy(&stream->queue_mutex);
              g_free(stream);
    -@@ hw/virtio/virtio-snd.c: static uint32_t virtio_snd_pcm_prepare_impl(VirtIOSound *s, uint32_t stream_id)
    +@@ hw/virtio/virtio-snd.c: static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id)
                                               virtio_snd_pcm_out_cb,
                                               &as);
          } else {
    @@ hw/virtio/virtio-snd.c: static void virtio_snd_handle_pcm_start_stop(VirtIOSound
     +        } else {
     +            AUD_set_active_in(stream->voice.in, start);
              }
    -     } else {
    -         error_report("Invalid stream id: %"PRIu32, req.stream_id);
    +         /* remove previous buffers. */
    +         WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
     @@ hw/virtio/virtio-snd.c: static void virtio_snd_handle_pcm_release(VirtIOSound *s,
               */
              virtio_snd_process_cmdq(stream->s);
    @@ hw/virtio/virtio-snd.c: tx_err:
      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_tx,
    --                              virtio_snd_handle_xfer,
    -+                              virtio_snd_handle_tx_xfer,
    -+                              virtio_snd_handle_rx_xfer,
    -                               errp);
    - }
    +     vsnd->queues[VIRTIO_SND_VQ_EVENT] =
    +         virtio_add_queue(vdev, 64, virtio_snd_handle_event);
    +     vsnd->queues[VIRTIO_SND_VQ_TX] =
    +-        virtio_add_queue(vdev, 64, virtio_snd_handle_tx);
    ++        virtio_add_queue(vdev, 64, virtio_snd_handle_tx_xfer);
    +     vsnd->queues[VIRTIO_SND_VQ_RX] =
    +-        virtio_add_queue(vdev, 64, virtio_snd_handle_xfer);
    ++        virtio_add_queue(vdev, 64, virtio_snd_handle_rx_xfer);
    +     qemu_mutex_init(&vsnd->cmdq_mutex);
    +     QTAILQ_INIT(&vsnd->cmdq);
      
     @@ hw/virtio/virtio-snd.c: static void virtio_snd_pcm_out_cb(void *data, int available)
      }
    @@ hw/virtio/virtio-snd.c: static void virtio_snd_pcm_out_cb(void *data, int availa
      
          WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
     -        QSIMPLEQ_FOREACH_SAFE(block, &stream->queue, entry, next) {
    --            AUD_write(stream->voice.out, block->data, block->size);
    +-            AUD_write(stream->voice.out, block->data + block->offset, block->size);
     -            virtqueue_push(block->vq, block->elem, sizeof(block->elem));
     -            virtio_notify(VIRTIO_DEVICE(stream->s), block->vq);
     -            QSIMPLEQ_REMOVE(&stream->queue, block, VirtIOSoundPCMBlock, entry);
    @@ hw/virtio/virtio-snd.c: static void virtio_snd_pcm_out_cb(void *data, int availa
     +{
     +    virtio_snd_pcm_flush(
     +            AUD_write(stream->voice.out,
    -+                              block->data,
    -+                              block->size);
    ++                      block->data + block->offset,
    ++                      block->size);
     +            );
     +}
     +
12:  6bed902247 = 12:  69eb5f4fba docs/system: add basic virtio-snd documentation

base-commit: 50e7a40af372ee5931c99ef7390f5d3d6fbf6ec4

Comments

Alex Bennée Aug. 30, 2023, 1:40 p.m. UTC | #1
Emmanouil Pitsidianakis <manos.pitsidianakis@linaro.org> writes:

> This patch series adds an audio device implementing the recent virtio 
> sound spec (1.2) and a corresponding PCI wrapper device.

And you can have a:

Tested-by: Alex Bennée <alex.bennee@linaro.org>

for the whole series.

mst,

are you going to pull via your tree?
Volker Rümelin Sept. 4, 2023, 7:20 a.m. UTC | #2
Am 28.08.23 um 21:54 schrieb Emmanouil Pitsidianakis:
> This patch series adds an audio device implementing the recent virtio
> sound spec (1.2) and a corresponding PCI wrapper device.

Hi Manos,

I have a few more general comments.

All qemu_log_mask() format strings need a trailing \n.

I still hear a lot of playback dropouts. I had planned to look at the 
playback code, but I didn't have the time until now.

Compared to v6 audio recording has improved but there are bugs. When I 
start QEMU with -audiodev 
pipewire,out.frequency=48000,in.frequency=48000,id=audio0 there are two 
either uninitialized or stale samples every 25ms in the recorded audio 
stream.

To reproduce the issue start audacity on the host and generate a 2s 
square wave tone with 315Hz and an amplitude of 0.8. Use pavucontrol to 
select the monitor of your host playback device as QEMU recording 
device. In the guest start recording with audacity. Start playback of 
the generated square wave on the host. Stop recording in the guest and 
have a look at a 200ms sequence of the recorded square wave and notice 
the wrong samples every 25ms.

When I start QEMU with -audiodev 
pipewire,out.mixing-engine=off,in.mixing-engine=off,id=audio0 audio 
recording starts but the recorded stream immediately stalls.

With best regards,
Volker

> v8 can be found online at:
>
> https://gitlab.com/epilys/qemu/-/tree/virtio-snd-v8
>
> Ref 69eb5f4fbae731f5fc05dea8a5f4b656e0de127f
>
> Main differences with v7 patch series [^v7]
> <cover.1692731646.git.manos.pitsidianakis@linaro.org>:
>
> - Addressed [^v7] review comments.
>    Functions that were called from more than one place for code re-use
>    are not created until they are actually needed.
> - Fixed cases where block->offset was not respected in Playback
>
>
Manos Pitsidianakis Sept. 4, 2023, 10:01 a.m. UTC | #3
Hello Volker :)

On Mon, 04 Sep 2023 10:20, Volker Rümelin <vr_qemu@t-online.de> wrote:
>All qemu_log_mask() format strings need a trailing \n.

Thank you, will fix it!

>I still hear a lot of playback dropouts. I had planned to look at the 
>playback code, but I didn't have the time until now.
>
>Compared to v6 audio recording has improved but there are bugs. When I 
>start QEMU with -audiodev 
>pipewire,out.frequency=48000,in.frequency=48000,id=audio0 there are two 
>either uninitialized or stale samples every 25ms in the recorded audio 
>stream.
>
>To reproduce the issue start audacity on the host and generate a 2s 
>square wave tone with 315Hz and an amplitude of 0.8. Use pavucontrol to 
>select the monitor of your host playback device as QEMU recording 
>device. In the guest start recording with audacity. Start playback of 
>the generated square wave on the host. Stop recording in the guest and 
>have a look at a 200ms sequence of the recorded square wave and notice 
>the wrong samples every 25ms.

We've noticed this and decided to fix it in the future. I think the 
problem lies when PCM release is called from the guest. Quoting the 
spec:

  The device MUST complete all pending I/O messages for the specified 
  stream ID.
  The device MUST NOT complete the control request while there are 
  pending I/O messages for the specified stream ID.

When RELEASE is received, buffers are simply dropped. This is pure 
conjecture but I think creating an in-device buffer could solve this.
Unless the bug is found to be caused by something else, I settled on 
accepting it for this patch series because it is spec conformant.

>When I start QEMU with -audiodev 
>pipewire,out.mixing-engine=off,in.mixing-engine=off,id=audio0 audio 
>recording starts but the recorded stream immediately stalls.

Can you elaborate? Do you mean you repeat the same process as before, 
but the stall happens immediately? I personally rarely get any drops I 
could notice, only one or two for many minutes of playback / capture. I 
also could not reproduce exactly the same behavior you had in the 
previous version. The bugs *were* there but it was not as severe. Maybe 
it's a hardware performance issue? Can someone else test this too? It'd 
be helpful.

Thank you very much for your help,
Manos
Alex Bennée Sept. 4, 2023, 12:11 p.m. UTC | #4
Manos Pitsidianakis <manos.pitsidianakis@linaro.org> writes:

> Hello Volker :)
>
> On Mon, 04 Sep 2023 10:20, Volker Rümelin <vr_qemu@t-online.de> wrote:
>>All qemu_log_mask() format strings need a trailing \n.
>
> Thank you, will fix it!
>
>> I still hear a lot of playback dropouts. I had planned to look at
>> the playback code, but I didn't have the time until now.
>>
>> Compared to v6 audio recording has improved but there are bugs. When
>> I start QEMU with -audiodev
>> pipewire,out.frequency=48000,in.frequency=48000,id=audio0 there are
>> two either uninitialized or stale samples every 25ms in the recorded
>> audio stream.
>>
>> To reproduce the issue start audacity on the host and generate a 2s
>> square wave tone with 315Hz and an amplitude of 0.8. Use pavucontrol
>> to select the monitor of your host playback device as QEMU recording
>> device. In the guest start recording with audacity. Start playback
>> of the generated square wave on the host. Stop recording in the
>> guest and have a look at a 200ms sequence of the recorded square
>> wave and notice the wrong samples every 25ms.
>
> We've noticed this and decided to fix it in the future. I think the
> problem lies when PCM release is called from the guest. Quoting the
> spec:
>
>  The device MUST complete all pending I/O messages for the specified
>  stream ID.
>  The device MUST NOT complete the control request while there are
>  pending I/O messages for the specified stream ID.
>
> When RELEASE is received, buffers are simply dropped. This is pure
> conjecture but I think creating an in-device buffer could solve this.
> Unless the bug is found to be caused by something else, I settled on
> accepting it for this patch series because it is spec conformant.

Volker,

Can you run with:

  -d trace:virtio_snd\*

to confirm you are seeing the same behaviour. The experience I had with
ogg123 in an emulated guest was it would work fine but then the next run
I would get audio corruption. You can see this if you see lots of
START/STOP/RELEASE messages constantly restarting things. If you are
getting corruption without this pattern that is something else which we
should investigate before merging.

>
>> When I start QEMU with -audiodev
>> pipewire,out.mixing-engine=off,in.mixing-engine=off,id=audio0 audio
>> recording starts but the recorded stream immediately stalls.
>
> Can you elaborate? Do you mean you repeat the same process as before,
> but the stall happens immediately? I personally rarely get any drops I
> could notice, only one or two for many minutes of playback / capture.
> I also could not reproduce exactly the same behavior you had in the
> previous version. The bugs *were* there but it was not as severe.
> Maybe it's a hardware performance issue? Can someone else test this
> too? It'd be helpful.
>
> Thank you very much for your help,
> Manos
Volker Rümelin Sept. 5, 2023, 6:03 a.m. UTC | #5
Am 04.09.23 um 14:11 schrieb Alex Bennée:
> Manos Pitsidianakis <manos.pitsidianakis@linaro.org> writes:
>
>> Hello Volker :)
>>
>> On Mon, 04 Sep 2023 10:20, Volker Rümelin <vr_qemu@t-online.de> wrote:
>>> All qemu_log_mask() format strings need a trailing \n.
>> Thank you, will fix it!
>>
>>> I still hear a lot of playback dropouts. I had planned to look at
>>> the playback code, but I didn't have the time until now.
>>>
>>> Compared to v6 audio recording has improved but there are bugs. When
>>> I start QEMU with -audiodev
>>> pipewire,out.frequency=48000,in.frequency=48000,id=audio0 there are
>>> two either uninitialized or stale samples every 25ms in the recorded
>>> audio stream.
>>>
>>> To reproduce the issue start audacity on the host and generate a 2s
>>> square wave tone with 315Hz and an amplitude of 0.8. Use pavucontrol
>>> to select the monitor of your host playback device as QEMU recording
>>> device. In the guest start recording with audacity. Start playback
>>> of the generated square wave on the host. Stop recording in the
>>> guest and have a look at a 200ms sequence of the recorded square
>>> wave and notice the wrong samples every 25ms.
>> We've noticed this and decided to fix it in the future. I think the
>> problem lies when PCM release is called from the guest. Quoting the
>> spec:
>>
>>   The device MUST complete all pending I/O messages for the specified
>>   stream ID.
>>   The device MUST NOT complete the control request while there are
>>   pending I/O messages for the specified stream ID.
>>
>> When RELEASE is received, buffers are simply dropped. This is pure
>> conjecture but I think creating an in-device buffer could solve this.
>> Unless the bug is found to be caused by something else, I settled on
>> accepting it for this patch series because it is spec conformant.
> Volker,
>
> Can you run with:
>
>    -d trace:virtio_snd\*
>
> to confirm you are seeing the same behaviour. The experience I had with
> ogg123 in an emulated guest was it would work fine but then the next run
> I would get audio corruption. You can see this if you see lots of
> START/STOP/RELEASE messages constantly restarting things. If you are
> getting corruption without this pattern that is something else which we
> should investigate before merging.

Hi Alex,

I only see a START message when I start recording with audacity and a 
STOP message approximately 5s after I stop recording. This is when guest 
PulseAudio disables the virtio-sound device.

9881@1693892230.558732:virtio_snd_handle_ctrl snd 0x55ac9e6eb590: handle 
ctrl event for queue 0x55ac9e6f4160
9881@1693892230.558780:virtio_snd_handle_code ctrl code msg val = 257 == 
VIRTIO_SND_R_PCM_SET_PARAMS
9881@1693892230.558797:virtio_snd_handle_pcm_set_params 
VIRTIO_SND_PCM_SET_PARAMS called for stream 1
9881@1693892230.559132:virtio_snd_handle_ctrl snd 0x55ac9e6eb590: handle 
ctrl event for queue 0x55ac9e6f4160
9881@1693892230.559158:virtio_snd_handle_code ctrl code msg val = 258 == 
VIRTIO_SND_R_PCM_PREPARE
9881@1693892230.562202:virtio_snd_handle_rx_xfer rx queue callback called
9881@1693892230.562365:virtio_snd_handle_ctrl snd 0x55ac9e6eb590: handle 
ctrl event for queue 0x55ac9e6f4160
9881@1693892230.562395:virtio_snd_handle_code ctrl code msg val = 260 == 
VIRTIO_SND_R_PCM_START
9881@1693892230.562411:virtio_snd_handle_pcm_start_stop 
VIRTIO_SND_R_PCM_START called for stream 1
9881@1693892230.562557:virtio_snd_handle_rx_xfer rx queue callback called
9881@1693892230.810029:virtio_snd_handle_rx_xfer rx queue callback called
9881@1693892230.840194:virtio_snd_handle_rx_xfer rx queue callback called
9881@1693892230.860279:virtio_snd_handle_rx_xfer rx queue callback called

... a lot of 'virtio_snd_handle_rx_xfer rx queue callback called' 
messages every 20ms - 30ms

9881@1693892238.510774:virtio_snd_handle_rx_xfer rx queue callback called
9881@1693892238.530895:virtio_snd_handle_rx_xfer rx queue callback called
9881@1693892238.561123:virtio_snd_handle_rx_xfer rx queue callback called
9881@1693892238.566280:virtio_snd_handle_ctrl snd 0x55ac9e6eb590: handle 
ctrl event for queue 0x55ac9e6f4160
9881@1693892238.566290:virtio_snd_handle_code ctrl code msg val = 261 == 
VIRTIO_SND_R_PCM_STOP
9881@1693892238.566293:virtio_snd_handle_pcm_start_stop 
VIRTIO_SND_R_PCM_STOP called for stream 1
9881@1693892238.566415:virtio_snd_handle_ctrl snd 0x55ac9e6eb590: handle 
ctrl event for queue 0x55ac9e6f4160
9881@1693892238.566424:virtio_snd_handle_code ctrl code msg val = 259 == 
VIRTIO_SND_R_PCM_RELEASE
9881@1693892238.566428:virtio_snd_handle_pcm_release 
VIRTIO_SND_PCM_RELEASE called for stream 1

With best regards,
Volker

>>> When I start QEMU with -audiodev
>>> pipewire,out.mixing-engine=off,in.mixing-engine=off,id=audio0 audio
>>> recording starts but the recorded stream immediately stalls.
>> Can you elaborate? Do you mean you repeat the same process as before,
>> but the stall happens immediately? I personally rarely get any drops I
>> could notice, only one or two for many minutes of playback / capture.
>> I also could not reproduce exactly the same behavior you had in the
>> previous version. The bugs *were* there but it was not as severe.
>> Maybe it's a hardware performance issue? Can someone else test this
>> too? It'd be helpful.
>>
>> Thank you very much for your help,
>> Manos
>
Volker Rümelin Sept. 5, 2023, 6:56 a.m. UTC | #6
Am 04.09.23 um 12:01 schrieb Manos Pitsidianakis:
> Hello Volker :)
>
> On Mon, 04 Sep 2023 10:20, Volker Rümelin <vr_qemu@t-online.de> wrote:
>> All qemu_log_mask() format strings need a trailing \n.
>
> Thank you, will fix it!
>
>> I still hear a lot of playback dropouts. I had planned to look at the 
>> playback code, but I didn't have the time until now.
>>
>> Compared to v6 audio recording has improved but there are bugs. When 
>> I start QEMU with -audiodev 
>> pipewire,out.frequency=48000,in.frequency=48000,id=audio0 there are 
>> two either uninitialized or stale samples every 25ms in the recorded 
>> audio stream.
>>
>> To reproduce the issue start audacity on the host and generate a 2s 
>> square wave tone with 315Hz and an amplitude of 0.8. Use pavucontrol 
>> to select the monitor of your host playback device as QEMU recording 
>> device. In the guest start recording with audacity. Start playback of 
>> the generated square wave on the host. Stop recording in the guest 
>> and have a look at a 200ms sequence of the recorded square wave and 
>> notice the wrong samples every 25ms.
>
> We've noticed this and decided to fix it in the future. I think the 
> problem lies when PCM release is called from the guest. Quoting the spec:
>
>  The device MUST complete all pending I/O messages for the specified 
>  stream ID.
>  The device MUST NOT complete the control request while there are 
>  pending I/O messages for the specified stream ID.
>
> When RELEASE is received, buffers are simply dropped. This is pure 
> conjecture but I think creating an in-device buffer could solve this.
> Unless the bug is found to be caused by something else, I settled on 
> accepting it for this patch series because it is spec conformant.
>
>> When I start QEMU with -audiodev 
>> pipewire,out.mixing-engine=off,in.mixing-engine=off,id=audio0 audio 
>> recording starts but the recorded stream immediately stalls.
>
> Can you elaborate? Do you mean you repeat the same process as before, 
> but the stall happens immediately? I personally rarely get any drops I 
> could notice, only one or two for many minutes of playback / capture. 
> I also could not reproduce exactly the same behavior you had in the 
> previous version. The bugs *were* there but it was not as severe. 
> Maybe it's a hardware performance issue? Can someone else test this 
> too? It'd be helpful.

For this test I only start QEMU with the mixing engine disabled. When I 
start recording with audacity, audacity reports 'Recording' in the 
status line but it actually doesn't record. The recording marker in the 
tracks window stays a 0.

I don't think it's a hardware performance issue. Other QEMU audio 
devices don't show this behaviour.

With best regards,
Volker

>
> Thank you very much for your help,
> Manos
Matias Ezequiel Vara Larsen Sept. 6, 2023, 8:39 a.m. UTC | #7
On Mon, Aug 28, 2023 at 10:54:57PM +0300, Emmanouil Pitsidianakis wrote:
> This patch series adds an audio device implementing the recent virtio 
> sound spec (1.2) and a corresponding PCI wrapper device.
> 
> v8 can be found online at:
> 
> https://gitlab.com/epilys/qemu/-/tree/virtio-snd-v8
> 
Hello Manos, 

I have been testing these patches in a 6.4.6 Linux guest by using the
command:

`aplay /usr/share/sounds/alsa/Front_Left.wav`

There is some audio that is reproduced twice, such as "Front ... Front
Left". I have also observed this in the virtio-sound vhost-user-device.
I'm still trying to figure out why this is happening.

Thanks, Matias.