* [PATCH v2] audio: Add sndio backend
@ 2021-12-17 9:38 Alexandre Ratchov
2021-12-18 15:16 ` Volker Rümelin
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Alexandre Ratchov @ 2021-12-17 9:38 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann, Brad
sndio is the native API used by OpenBSD, although it has been ported to
other *BSD's and Linux (packages for Ubuntu, Debian, Void, Arch, etc.).
Signed-off-by: Brad Smith <brad@comstyle.com>
Signed-off-by: Alexandre Ratchov <alex@caoua.org>
---
Thank you for the reviews and all the comments. Here's a second diff
with all the suggested changes:
- Replace ISC license by SPDX-License-Identifier header
- Fix units (milli- vs micro-) in comment about SNDIO_LATENCY_US
- Drop outdated comment about the "size" argument of sndio_get_buffer_out()
- Fix AUDIO_FORMAT_U32 handling (missing "break" statement)
- Set {read,write] methods to audio_generic_{read,write} (fixes craches)
- Check if backend is enabled in sndio_poll_event()
- Use https://sndio.org in description
- Mark options as available after 7.0 release (instead of 6.2)
- Describe sndio-specific options (dev, latency) in qemu-options.hx
- Add myself as reviewer to MAINTAINERS
- Style fixes: no space after function names, use 4-space indent
- Don't use "return foo()" if foo() returns void
- Include backend to audio_drivers_priority[]
Tested on OpenBSD, works as expected!
MAINTAINERS | 5 +
audio/audio.c | 1 +
audio/audio_template.h | 2 +
audio/meson.build | 1 +
audio/sndioaudio.c | 555 +++++++++++++++++++++++++++++++++++++++++
meson.build | 9 +-
meson_options.txt | 4 +-
qapi/audio.json | 25 +-
qemu-options.hx | 16 ++
tests/vm/freebsd | 3 +
10 files changed, 618 insertions(+), 3 deletions(-)
create mode 100644 audio/sndioaudio.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 7543eb4d59..76bdad064f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2307,6 +2307,7 @@ X: audio/jackaudio.c
X: audio/ossaudio.c
X: audio/paaudio.c
X: audio/sdlaudio.c
+X: audio/sndio.c
X: audio/spiceaudio.c
F: qapi/audio.json
@@ -2349,6 +2350,10 @@ R: Thomas Huth <huth@tuxfamily.org>
S: Odd Fixes
F: audio/sdlaudio.c
+Sndio Audio backend
+R: Alexandre Ratchov <alex@caoua.org>
+F: audio/sndio.c
+
Block layer core
M: Kevin Wolf <kwolf@redhat.com>
M: Hanna Reitz <hreitz@redhat.com>
diff --git a/audio/audio.c b/audio/audio.c
index 54a153c0ef..bad1ceb69e 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -2005,6 +2005,7 @@ void audio_create_pdos(Audiodev *dev)
CASE(OSS, oss, Oss);
CASE(PA, pa, Pa);
CASE(SDL, sdl, Sdl);
+ CASE(SNDIO, sndio, );
CASE(SPICE, spice, );
CASE(WAV, wav, );
diff --git a/audio/audio_template.h b/audio/audio_template.h
index c6714946aa..ecc5a0bc6d 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -337,6 +337,8 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev)
return qapi_AudiodevPaPerDirectionOptions_base(dev->u.pa.TYPE);
case AUDIODEV_DRIVER_SDL:
return qapi_AudiodevSdlPerDirectionOptions_base(dev->u.sdl.TYPE);
+ case AUDIODEV_DRIVER_SNDIO:
+ return dev->u.sndio.TYPE;
case AUDIODEV_DRIVER_SPICE:
return dev->u.spice.TYPE;
case AUDIODEV_DRIVER_WAV:
diff --git a/audio/meson.build b/audio/meson.build
index 462533bb8c..e24c86e7e6 100644
--- a/audio/meson.build
+++ b/audio/meson.build
@@ -17,6 +17,7 @@ foreach m : [
['pa', pulse, files('paaudio.c')],
['sdl', sdl, files('sdlaudio.c')],
['jack', jack, files('jackaudio.c')],
+ ['sndio', sndio, files('sndioaudio.c')],
['spice', spice, files('spiceaudio.c')]
]
if m[1].found()
diff --git a/audio/sndioaudio.c b/audio/sndioaudio.c
new file mode 100644
index 0000000000..ab2e80decf
--- /dev/null
+++ b/audio/sndioaudio.c
@@ -0,0 +1,555 @@
+/*
+ * SPDX-License-Identifier: ISC
+ *
+ * Copyright (c) 2019 Alexandre Ratchov <alex@caoua.org>
+ */
+
+/*
+ * TODO :
+ *
+ * Use a single device and open it in full-duplex rather than
+ * opening it twice (once for playback once for recording).
+ *
+ * This is the only way to ensure that playback doesn't drift with respect
+ * to recording, which is what guest systems expect.
+ */
+
+#include <poll.h>
+#include <sndio.h>
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/main-loop.h"
+#include "audio.h"
+#include "trace.h"
+
+#define AUDIO_CAP "sndio"
+#include "audio_int.h"
+
+/* default latency in microseconds if no option is set */
+#define SNDIO_LATENCY_US 50000
+
+typedef struct SndioVoice {
+ union {
+ HWVoiceOut out;
+ HWVoiceIn in;
+ } hw;
+ struct sio_par par;
+ struct sio_hdl *hdl;
+ struct pollfd *pfds;
+ struct pollindex {
+ struct SndioVoice *self;
+ int index;
+ } *pindexes;
+ unsigned char *buf;
+ size_t buf_size;
+ size_t sndio_pos;
+ size_t qemu_pos;
+ unsigned int mode;
+ unsigned int nfds;
+ bool enabled;
+} SndioVoice;
+
+typedef struct SndioConf {
+ const char *devname;
+ unsigned int latency;
+} SndioConf;
+
+/* needed for forward reference */
+static void sndio_poll_in(void *arg);
+static void sndio_poll_out(void *arg);
+
+/*
+ * stop polling descriptors
+ */
+static void sndio_poll_clear(SndioVoice *self)
+{
+ struct pollfd *pfd;
+ int i;
+
+ for (i = 0; i < self->nfds; i++) {
+ pfd = &self->pfds[i];
+ qemu_set_fd_handler(pfd->fd, NULL, NULL, NULL);
+ }
+
+ self->nfds = 0;
+}
+
+/*
+ * write data to the device until it blocks or
+ * all of our buffered data is written
+ */
+static void sndio_write(SndioVoice *self)
+{
+ size_t todo, n;
+
+ todo = self->qemu_pos - self->sndio_pos;
+
+ /*
+ * transfer data to device, until it blocks
+ */
+ while (todo > 0) {
+ n = sio_write(self->hdl, self->buf + self->sndio_pos, todo);
+ if (n == 0) {
+ break;
+ }
+ self->sndio_pos += n;
+ todo -= n;
+ }
+
+ if (self->sndio_pos == self->buf_size) {
+ /*
+ * we complete the block
+ */
+ self->sndio_pos = 0;
+ self->qemu_pos = 0;
+ }
+}
+
+/*
+ * read data from the device until it blocks or
+ * there no room any longer
+ */
+static void sndio_read(SndioVoice *self)
+{
+ size_t todo, n;
+
+ todo = self->buf_size - self->sndio_pos;
+
+ /*
+ * transfer data from the device, until it blocks
+ */
+ while (todo > 0) {
+ n = sio_read(self->hdl, self->buf + self->sndio_pos, todo);
+ if (n == 0) {
+ break;
+ }
+ self->sndio_pos += n;
+ todo -= n;
+ }
+}
+
+/*
+ * Set handlers for all descriptors libsndio needs to
+ * poll
+ */
+static void sndio_poll_wait(SndioVoice *self)
+{
+ struct pollfd *pfd;
+ int events, i;
+
+ events = 0;
+ if (self->mode == SIO_PLAY) {
+ if (self->sndio_pos < self->qemu_pos) {
+ events |= POLLOUT;
+ }
+ } else {
+ if (self->sndio_pos < self->buf_size) {
+ events |= POLLIN;
+ }
+ }
+
+ /*
+ * fill the given array of descriptors with the events sndio
+ * wants, they are different from our 'event' variable because
+ * sndio may use descriptors internally.
+ */
+ self->nfds = sio_pollfd(self->hdl, self->pfds, events);
+
+ for (i = 0; i < self->nfds; i++) {
+ pfd = &self->pfds[i];
+ if (pfd->fd < 0) {
+ continue;
+ }
+ qemu_set_fd_handler(pfd->fd,
+ (pfd->events & POLLIN) ? sndio_poll_in : NULL,
+ (pfd->events & POLLOUT) ? sndio_poll_out : NULL,
+ &self->pindexes[i]);
+ pfd->revents = 0;
+ }
+}
+
+/*
+ * call-back called when one of the descriptors
+ * became readable or writable
+ */
+static void sndio_poll_event(SndioVoice *self, int index, int event)
+{
+ int revents;
+
+ /*
+ * ensure we're not called twice this cycle
+ */
+ sndio_poll_clear(self);
+
+ /*
+ * make self->pfds[] look as we're returning from poll syscal,
+ * this is how sio_revents expects events to be.
+ */
+ self->pfds[index].revents = event;
+
+ /*
+ * tell sndio to handle events and return whether we can read or
+ * write without blocking.
+ */
+ revents = sio_revents(self->hdl, self->pfds);
+ if (self->mode == SIO_PLAY) {
+ if (revents & POLLOUT) {
+ sndio_write(self);
+ }
+
+ if (self->qemu_pos < self->buf_size) {
+ audio_run(self->hw.out.s, "sndio_out");
+ }
+ } else {
+ if (revents & POLLIN) {
+ sndio_read(self);
+ }
+
+ if (self->qemu_pos < self->sndio_pos) {
+ audio_run(self->hw.in.s, "sndio_in");
+ }
+ }
+
+ /*
+ * audio_run() may have changed state
+ */
+ if (self->enabled) {
+ sndio_poll_wait(self);
+ }
+}
+
+/*
+ * return a buffer where data to play can be stored,
+ * its size is stored in the location pointed by the size argument.
+ */
+static void *sndio_get_buffer_out(HWVoiceOut *hw, size_t *size)
+{
+ SndioVoice *self = (SndioVoice *) hw;
+
+ *size = self->buf_size - self->qemu_pos;
+ return self->buf + self->qemu_pos;
+}
+
+/*
+ * return a buffer where data to play can be stored
+ */
+static size_t sndio_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size)
+{
+ SndioVoice *self = (SndioVoice *) hw;
+
+ self->qemu_pos += size;
+ sndio_poll_wait(self);
+ return size;
+}
+
+/*
+ * return a buffer from where recorded data is available,
+ * its size is stored in the location pointed by the size argument.
+ * it may not exceed the initial value of "*size".
+ */
+static void *sndio_get_buffer_in(HWVoiceIn *hw, size_t *size)
+{
+ SndioVoice *self = (SndioVoice *) hw;
+ size_t todo, max_todo;
+
+ /*
+ * unlike the get_buffer_out() method, get_buffer_in()
+ * must return a buffer of at most the given size, see audio.c
+ */
+ max_todo = *size;
+
+ todo = self->sndio_pos - self->qemu_pos;
+ if (todo > max_todo) {
+ todo = max_todo;
+ }
+
+ *size = todo;
+ return self->buf + self->qemu_pos;
+}
+
+/*
+ * discard the given amount of recorded data
+ */
+static void sndio_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size)
+{
+ SndioVoice *self = (SndioVoice *) hw;
+
+ self->qemu_pos += size;
+ if (self->qemu_pos == self->buf_size) {
+ self->qemu_pos = 0;
+ self->sndio_pos = 0;
+ }
+ sndio_poll_wait(self);
+}
+
+/*
+ * call-back called when one of our descriptors becomes writable
+ */
+static void sndio_poll_out(void *arg)
+{
+ struct pollindex *pindex = (struct pollindex *) arg;
+
+ sndio_poll_event(pindex->self, pindex->index, POLLOUT);
+}
+
+/*
+ * call-back called when one of our descriptors becomes readable
+ */
+static void sndio_poll_in(void *arg)
+{
+ struct pollindex *pindex = (struct pollindex *) arg;
+
+ sndio_poll_event(pindex->self, pindex->index, POLLIN);
+}
+
+static void sndio_fini(SndioVoice *self)
+{
+ if (self->hdl) {
+ sio_close(self->hdl);
+ self->hdl = NULL;
+ }
+
+ g_free(self->pfds);
+ g_free(self->pindexes);
+ g_free(self->buf);
+}
+
+static int sndio_init(SndioVoice *self,
+ struct audsettings *as, int mode, Audiodev *dev)
+{
+ AudiodevSndioOptions *opts = &dev->u.sndio;
+ unsigned long long latency;
+ const char *dev_name;
+ struct sio_par req;
+ unsigned int nch;
+ int i, nfds;
+
+ dev_name = opts->has_dev ? opts->dev : SIO_DEVANY;
+ latency = opts->has_latency ? opts->latency : SNDIO_LATENCY_US;
+
+ /* open the device in non-blocking mode */
+ self->hdl = sio_open(dev_name, mode, 1);
+ if (self->hdl == NULL) {
+ dolog("failed to open device\n");
+ return -1;
+ }
+
+ self->mode = mode;
+
+ sio_initpar(&req);
+
+ switch (as->fmt) {
+ case AUDIO_FORMAT_S8:
+ req.bits = 8;
+ req.sig = 1;
+ break;
+ case AUDIO_FORMAT_U8:
+ req.bits = 8;
+ req.sig = 0;
+ break;
+ case AUDIO_FORMAT_S16:
+ req.bits = 16;
+ req.sig = 1;
+ break;
+ case AUDIO_FORMAT_U16:
+ req.bits = 16;
+ req.sig = 0;
+ break;
+ case AUDIO_FORMAT_S32:
+ req.bits = 32;
+ req.sig = 1;
+ break;
+ case AUDIO_FORMAT_U32:
+ req.bits = 32;
+ req.sig = 0;
+ break;
+ default:
+ dolog("unknown audio sample format\n");
+ return -1;
+ }
+
+ if (req.bits > 8) {
+ req.le = as->endianness ? 0 : 1;
+ }
+
+ req.rate = as->freq;
+ if (mode == SIO_PLAY) {
+ req.pchan = as->nchannels;
+ } else {
+ req.rchan = as->nchannels;
+ }
+
+ /* set on-device buffer size */
+ req.appbufsz = req.rate * latency / 1000000;
+
+ if (!sio_setpar(self->hdl, &req)) {
+ dolog("failed set audio params\n");
+ goto fail;
+ }
+
+ if (!sio_getpar(self->hdl, &self->par)) {
+ dolog("failed get audio params\n");
+ goto fail;
+ }
+
+ nch = (mode == SIO_PLAY) ? self->par.pchan : self->par.rchan;
+
+ /*
+ * With the default setup, sndio supports any combination of parameters
+ * so these checks are mostly to catch configuration errors.
+ */
+ if (self->par.bits != req.bits || self->par.bps != req.bits / 8 ||
+ self->par.sig != req.sig || (req.bits > 8 && self->par.le != req.le) ||
+ self->par.rate != as->freq || nch != as->nchannels) {
+ dolog("unsupported audio params\n");
+ goto fail;
+ }
+
+ /*
+ * we use one block as buffer size; this is how
+ * transfers get well aligned
+ */
+ self->buf_size = self->par.round * self->par.bps * nch;
+
+ self->buf = g_malloc(self->buf_size);
+ if (self->buf == NULL) {
+ dolog("failed to allocate audio buffer\n");
+ goto fail;
+ }
+
+ nfds = sio_nfds(self->hdl);
+
+ self->pfds = g_malloc_n(nfds, sizeof(struct pollfd));
+ if (self->pfds == NULL) {
+ dolog("failed to allocate pollfd structures\n");
+ goto fail;
+ }
+
+ self->pindexes = g_malloc_n(nfds, sizeof(struct pollindex));
+ if (self->pindexes == NULL) {
+ dolog("failed to allocate pollindex structures\n");
+ goto fail;
+ }
+
+ for (i = 0; i < nfds; i++) {
+ self->pindexes[i].self = self;
+ self->pindexes[i].index = i;
+ }
+
+ return 0;
+fail:
+ sndio_fini(self);
+ return -1;
+}
+
+static void sndio_enable(SndioVoice *self, bool enable)
+{
+ if (enable) {
+ sio_start(self->hdl);
+ self->enabled = true;
+ sndio_poll_wait(self);
+ } else {
+ self->enabled = false;
+ sndio_poll_clear(self);
+ sio_stop(self->hdl);
+ }
+}
+
+static void sndio_enable_out(HWVoiceOut *hw, bool enable)
+{
+ SndioVoice *self = (SndioVoice *) hw;
+
+ sndio_enable(self, enable);
+}
+
+static void sndio_enable_in(HWVoiceIn *hw, bool enable)
+{
+ SndioVoice *self = (SndioVoice *) hw;
+
+ sndio_enable(self, enable);
+}
+
+static int sndio_init_out(HWVoiceOut *hw, struct audsettings *as, void *opaque)
+{
+ SndioVoice *self = (SndioVoice *) hw;
+
+ if (sndio_init(self, as, SIO_PLAY, opaque) == -1) {
+ return -1;
+ }
+
+ audio_pcm_init_info(&hw->info, as);
+ hw->samples = self->par.round;
+ return 0;
+}
+
+static int sndio_init_in(HWVoiceIn *hw, struct audsettings *as, void *opaque)
+{
+ SndioVoice *self = (SndioVoice *) hw;
+
+ if (sndio_init(self, as, SIO_REC, opaque) == -1) {
+ return -1;
+ }
+
+ audio_pcm_init_info(&hw->info, as);
+ hw->samples = self->par.round;
+ return 0;
+}
+
+static void sndio_fini_out(HWVoiceOut *hw)
+{
+ SndioVoice *self = (SndioVoice *) hw;
+
+ sndio_fini(self);
+}
+
+static void sndio_fini_in(HWVoiceIn *hw)
+{
+ SndioVoice *self = (SndioVoice *) hw;
+
+ sndio_fini(self);
+}
+
+static void *sndio_audio_init(Audiodev *dev)
+{
+ assert(dev->driver == AUDIODEV_DRIVER_SNDIO);
+ return dev;
+}
+
+static void sndio_audio_fini(void *opaque)
+{
+}
+
+static struct audio_pcm_ops sndio_pcm_ops = {
+ .init_out = sndio_init_out,
+ .fini_out = sndio_fini_out,
+ .enable_out = sndio_enable_out,
+ .write = audio_generic_write,
+ .get_buffer_out = sndio_get_buffer_out,
+ .put_buffer_out = sndio_put_buffer_out,
+ .init_in = sndio_init_in,
+ .fini_in = sndio_fini_in,
+ .read = audio_generic_read,
+ .enable_in = sndio_enable_in,
+ .get_buffer_in = sndio_get_buffer_in,
+ .put_buffer_in = sndio_put_buffer_in,
+};
+
+static struct audio_driver sndio_audio_driver = {
+ .name = "sndio",
+ .descr = "sndio https://sndio.org",
+ .init = sndio_audio_init,
+ .fini = sndio_audio_fini,
+ .pcm_ops = &sndio_pcm_ops,
+ .can_be_default = 1,
+ .max_voices_out = INT_MAX,
+ .max_voices_in = INT_MAX,
+ .voice_size_out = sizeof(SndioVoice),
+ .voice_size_in = sizeof(SndioVoice)
+};
+
+static void register_audio_sndio(void)
+{
+ audio_driver_register(&sndio_audio_driver);
+}
+
+type_init(register_audio_sndio);
diff --git a/meson.build b/meson.build
index 96de1a6ef9..92dc9e3973 100644
--- a/meson.build
+++ b/meson.build
@@ -554,6 +554,11 @@ if not get_option('jack').auto() or have_system
jack = dependency('jack', required: get_option('jack'),
method: 'pkg-config', kwargs: static_kwargs)
endif
+sndio = not_found
+if not get_option('sndio').auto() or have_system
+ sndio = dependency('sndio', required: get_option('sndio'),
+ method: 'pkg-config', kwargs: static_kwargs)
+endif
spice_protocol = not_found
if not get_option('spice_protocol').auto() or have_system
@@ -1311,6 +1316,7 @@ if have_system
'oss': oss.found(),
'pa': pulse.found(),
'sdl': sdl.found(),
+ 'sndio': sndio.found(),
}
foreach k, v: audio_drivers_available
config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
@@ -1318,7 +1324,7 @@ if have_system
# Default to native drivers first, OSS second, SDL third
audio_drivers_priority = \
- [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \
+ [ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \
(targetos == 'linux' ? [] : [ 'sdl' ])
audio_drivers_default = []
foreach k: audio_drivers_priority
@@ -3385,6 +3391,7 @@ if vnc.found()
endif
if targetos not in ['darwin', 'haiku', 'windows']
summary_info += {'OSS support': oss}
+ summary_info += {'sndio support': sndio}
elif targetos == 'darwin'
summary_info += {'CoreAudio support': coreaudio}
elif targetos == 'windows'
diff --git a/meson_options.txt b/meson_options.txt
index e392323732..7334ced291 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -13,7 +13,7 @@ option('sphinx_build', type : 'string', value : '',
option('default_devices', type : 'boolean', value : true,
description: 'Include a default selection of devices in emulators')
option('audio_drv_list', type: 'array', value: ['default'],
- choices: ['alsa', 'coreaudio', 'default', 'dsound', 'jack', 'oss', 'pa', 'sdl'],
+ choices: ['alsa', 'coreaudio', 'default', 'dsound', 'jack', 'oss', 'pa', 'sdl', 'sndio'],
description: 'Set audio driver list')
option('fuzzing_engine', type : 'string', value : '',
description: 'fuzzing engine library for OSS-Fuzz')
@@ -184,6 +184,8 @@ option('oss', type: 'feature', value: 'auto',
description: 'OSS sound support')
option('pa', type: 'feature', value: 'auto',
description: 'PulseAudio sound support')
+option('sndio', type: 'feature', value: 'auto',
+ description: 'sndio sound support')
option('vhost_user_blk_server', type: 'feature', value: 'auto',
description: 'build vhost-user-blk server')
diff --git a/qapi/audio.json b/qapi/audio.json
index 9cba0df8a4..b97a6de3be 100644
--- a/qapi/audio.json
+++ b/qapi/audio.json
@@ -105,6 +105,28 @@
'*out': 'AudiodevAlsaPerDirectionOptions',
'*threshold': 'uint32' } }
+##
+# @AudiodevSndioOptions:
+#
+# Options of the sndio audio backend.
+#
+# @in: options of the capture stream
+#
+# @out: options of the playback stream
+#
+# @dev: the name of the sndio device to use (default 'default')
+#
+# @latency: play buffer size (in microseconds)
+#
+# Since: 7.0
+##
+{ 'struct': 'AudiodevSndioOptions',
+ 'data': {
+ '*in': 'AudiodevPerDirectionOptions',
+ '*out': 'AudiodevPerDirectionOptions',
+ '*dev': 'str',
+ '*latency': 'uint32'} }
+
##
# @AudiodevCoreaudioPerDirectionOptions:
#
@@ -387,7 +409,7 @@
##
{ 'enum': 'AudiodevDriver',
'data': [ 'none', 'alsa', 'coreaudio', 'dsound', 'jack', 'oss', 'pa',
- 'sdl', 'spice', 'wav' ] }
+ 'sdl', 'sndio', 'spice', 'wav' ] }
##
# @Audiodev:
@@ -417,5 +439,6 @@
'oss': 'AudiodevOssOptions',
'pa': 'AudiodevPaOptions',
'sdl': 'AudiodevSdlOptions',
+ 'sndio': 'AudiodevSndioOptions',
'spice': 'AudiodevGenericOptions',
'wav': 'AudiodevWavOptions' } }
diff --git a/qemu-options.hx b/qemu-options.hx
index ae2c6dbbfc..699c7c42bf 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -657,6 +657,9 @@ DEF("audiodev", HAS_ARG, QEMU_OPTION_audiodev,
"-audiodev sdl,id=id[,prop[=value][,...]]\n"
" in|out.buffer-count= number of buffers\n"
#endif
+#ifdef CONFIG_AUDIO_SNDIO
+ "-audiodev sndio,id=id[,prop[=value][,...]]\n"
+#endif
#ifdef CONFIG_SPICE
"-audiodev spice,id=id[,prop[=value][,...]]\n"
#endif
@@ -820,6 +823,19 @@ SRST
``in|out.buffer-count=count``
Sets the count of the buffers.
+``-audiodev sndio,id=id[,prop[=value][,...]]``
+ Creates a backend using SNDIO. This backend is available on
+ OpenBSD and most other Unix-like systems.
+
+ Sndio specific options are:
+
+ ``in|out.dev=device``
+ Specify the sndio device to use for input and/or output. Default
+ is ``default``.
+
+ ``in|out.latency=usecs``
+ Sets the desired period length in microseconds.
+
``-audiodev spice,id=id[,prop[=value][,...]]``
Creates a backend that sends audio through SPICE. This backend
requires ``-spice`` and automatically selected in that case, so
diff --git a/tests/vm/freebsd b/tests/vm/freebsd
index 6e20e84322..a387f5c9df 100755
--- a/tests/vm/freebsd
+++ b/tests/vm/freebsd
@@ -63,6 +63,9 @@ class FreeBSDVM(basevm.BaseVM):
# libs: migration
"zstd",
+
+ # libs: sndio
+ "sndio",
]
# TODO: Enable gnutls again once FreeBSD's libtasn1 got fixed
--
2.34.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2] audio: Add sndio backend
2021-12-17 9:38 [PATCH v2] audio: Add sndio backend Alexandre Ratchov
@ 2021-12-18 15:16 ` Volker Rümelin
2021-12-19 21:07 ` Volker Rümelin
` (2 subsequent siblings)
3 siblings, 0 replies; 8+ messages in thread
From: Volker Rümelin @ 2021-12-18 15:16 UTC (permalink / raw)
To: Alexandre Ratchov, Gerd Hoffmann; +Cc: qemu-devel, Brad
Hi Alexandre,
> sndio is the native API used by OpenBSD, although it has been ported to
> other *BSD's and Linux (packages for Ubuntu, Debian, Void, Arch, etc.).
>
> Signed-off-by: Brad Smith <brad@comstyle.com>
> Signed-off-by: Alexandre Ratchov <alex@caoua.org>
> ---
>
> Thank you for the reviews and all the comments. Here's a second diff
> with all the suggested changes:
>
> - Replace ISC license by SPDX-License-Identifier header
> - Fix units (milli- vs micro-) in comment about SNDIO_LATENCY_US
> - Drop outdated comment about the "size" argument of sndio_get_buffer_out()
> - Fix AUDIO_FORMAT_U32 handling (missing "break" statement)
> - Set {read,write] methods to audio_generic_{read,write} (fixes craches)
> - Check if backend is enabled in sndio_poll_event()
> - Use https://sndio.org in description
> - Mark options as available after 7.0 release (instead of 6.2)
> - Describe sndio-specific options (dev, latency) in qemu-options.hx
> - Add myself as reviewer to MAINTAINERS
> - Style fixes: no space after function names, use 4-space indent
> - Don't use "return foo()" if foo() returns void
> - Include backend to audio_drivers_priority[]
>
> Tested on OpenBSD, works as expected!
>
> MAINTAINERS | 5 +
> audio/audio.c | 1 +
> audio/audio_template.h | 2 +
> audio/meson.build | 1 +
> audio/sndioaudio.c | 555 +++++++++++++++++++++++++++++++++++++++++
> meson.build | 9 +-
> meson_options.txt | 4 +-
> qapi/audio.json | 25 +-
> qemu-options.hx | 16 ++
> tests/vm/freebsd | 3 +
> 10 files changed, 618 insertions(+), 3 deletions(-)
> create mode 100644 audio/sndioaudio.c
Tested on Linux.
Reviewed-by: Volker Rümelin <vr_qemu@t-online.de>
Tested-by: Volker Rümelin <vr_qemu@t-online.de>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] audio: Add sndio backend
2021-12-17 9:38 [PATCH v2] audio: Add sndio backend Alexandre Ratchov
2021-12-18 15:16 ` Volker Rümelin
@ 2021-12-19 21:07 ` Volker Rümelin
2022-01-16 4:32 ` Brad Smith
2021-12-20 15:41 ` Christian Schoenebeck
2021-12-23 15:10 ` WANG Xuerui
3 siblings, 1 reply; 8+ messages in thread
From: Volker Rümelin @ 2021-12-19 21:07 UTC (permalink / raw)
To: Alexandre Ratchov, Gerd Hoffmann; +Cc: qemu-devel, Brad
Hi Alexandre,
> sndio is the native API used by OpenBSD, although it has been ported to
> other *BSD's and Linux (packages for Ubuntu, Debian, Void, Arch, etc.).
>
> Signed-off-by: Brad Smith<brad@comstyle.com>
> Signed-off-by: Alexandre Ratchov<alex@caoua.org>
> ---
>
> Thank you for the reviews and all the comments. Here's a second diff
> with all the suggested changes:
>
> - Replace ISC license by SPDX-License-Identifier header
> - Fix units (milli- vs micro-) in comment about SNDIO_LATENCY_US
> - Drop outdated comment about the "size" argument of sndio_get_buffer_out()
> - Fix AUDIO_FORMAT_U32 handling (missing "break" statement)
> - Set {read,write] methods to audio_generic_{read,write} (fixes craches)
> - Check if backend is enabled in sndio_poll_event()
> - Usehttps://sndio.org in description
> - Mark options as available after 7.0 release (instead of 6.2)
> - Describe sndio-specific options (dev, latency) in qemu-options.hx
> - Add myself as reviewer to MAINTAINERS
> - Style fixes: no space after function names, use 4-space indent
> - Don't use "return foo()" if foo() returns void
> - Include backend to audio_drivers_priority[]
>
> Tested on OpenBSD, works as expected!
>
> MAINTAINERS | 5 +
> audio/audio.c | 1 +
> audio/audio_template.h | 2 +
> audio/meson.build | 1 +
> audio/sndioaudio.c | 555 +++++++++++++++++++++++++++++++++++++++++
> meson.build | 9 +-
> meson_options.txt | 4 +-
I just noticed you changed meson_options.txt but you forgot to
regenerate scripts/meson-buildoptions.sh with make update-buildoptions
in your build directory. See docs/devel/build-system.rst.
And I'm still convinced you should CC all maintainers of the files this
patch changes.
With best regards,
Volker
> qapi/audio.json | 25 +-
> qemu-options.hx | 16 ++
> tests/vm/freebsd | 3 +
> 10 files changed, 618 insertions(+), 3 deletions(-)
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] audio: Add sndio backend
2021-12-17 9:38 [PATCH v2] audio: Add sndio backend Alexandre Ratchov
2021-12-18 15:16 ` Volker Rümelin
2021-12-19 21:07 ` Volker Rümelin
@ 2021-12-20 15:41 ` Christian Schoenebeck
2021-12-23 13:00 ` Christian Schoenebeck
2022-01-13 9:57 ` Gerd Hoffmann
2021-12-23 15:10 ` WANG Xuerui
3 siblings, 2 replies; 8+ messages in thread
From: Christian Schoenebeck @ 2021-12-20 15:41 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel, Alexandre Ratchov, Brad
On Freitag, 17. Dezember 2021 10:38:32 CET Alexandre Ratchov wrote:
> sndio is the native API used by OpenBSD, although it has been ported to
> other *BSD's and Linux (packages for Ubuntu, Debian, Void, Arch, etc.).
>
> Signed-off-by: Brad Smith <brad@comstyle.com>
> Signed-off-by: Alexandre Ratchov <alex@caoua.org>
> ---
>
> Thank you for the reviews and all the comments. Here's a second diff
> with all the suggested changes:
>
> - Replace ISC license by SPDX-License-Identifier header
> - Fix units (milli- vs micro-) in comment about SNDIO_LATENCY_US
> - Drop outdated comment about the "size" argument of sndio_get_buffer_out()
> - Fix AUDIO_FORMAT_U32 handling (missing "break" statement)
> - Set {read,write] methods to audio_generic_{read,write} (fixes craches)
> - Check if backend is enabled in sndio_poll_event()
> - Use https://sndio.org in description
> - Mark options as available after 7.0 release (instead of 6.2)
> - Describe sndio-specific options (dev, latency) in qemu-options.hx
> - Add myself as reviewer to MAINTAINERS
> - Style fixes: no space after function names, use 4-space indent
> - Don't use "return foo()" if foo() returns void
> - Include backend to audio_drivers_priority[]
>
> Tested on OpenBSD, works as expected!
>
> MAINTAINERS | 5 +
> audio/audio.c | 1 +
> audio/audio_template.h | 2 +
> audio/meson.build | 1 +
> audio/sndioaudio.c | 555 +++++++++++++++++++++++++++++++++++++++++
> meson.build | 9 +-
> meson_options.txt | 4 +-
> qapi/audio.json | 25 +-
> qemu-options.hx | 16 ++
> tests/vm/freebsd | 3 +
> 10 files changed, 618 insertions(+), 3 deletions(-)
> create mode 100644 audio/sndioaudio.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 7543eb4d59..76bdad064f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2307,6 +2307,7 @@ X: audio/jackaudio.c
> X: audio/ossaudio.c
> X: audio/paaudio.c
> X: audio/sdlaudio.c
> +X: audio/sndio.c
> X: audio/spiceaudio.c
> F: qapi/audio.json
>
> @@ -2349,6 +2350,10 @@ R: Thomas Huth <huth@tuxfamily.org>
> S: Odd Fixes
> F: audio/sdlaudio.c
>
> +Sndio Audio backend
> +R: Alexandre Ratchov <alex@caoua.org>
> +F: audio/sndio.c
> +
Thanks Alexandre for volunteering as reviewer!
Gerd, would it be OK to set you as maintainer for now until new maintainer(s)
adopt audio sections? Or should this start with "S: Orphan" instead?
Best regards,
Christian Schoenebeck
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] audio: Add sndio backend
2021-12-20 15:41 ` Christian Schoenebeck
@ 2021-12-23 13:00 ` Christian Schoenebeck
2022-01-13 9:57 ` Gerd Hoffmann
1 sibling, 0 replies; 8+ messages in thread
From: Christian Schoenebeck @ 2021-12-23 13:00 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann, Alexandre Ratchov, Brad, Volker Rümelin
On Montag, 20. Dezember 2021 16:41:31 CET Christian Schoenebeck wrote:
> On Freitag, 17. Dezember 2021 10:38:32 CET Alexandre Ratchov wrote:
> > sndio is the native API used by OpenBSD, although it has been ported to
> > other *BSD's and Linux (packages for Ubuntu, Debian, Void, Arch, etc.).
> >
> > Signed-off-by: Brad Smith <brad@comstyle.com>
> > Signed-off-by: Alexandre Ratchov <alex@caoua.org>
> > ---
> >
> > Thank you for the reviews and all the comments. Here's a second diff
> > with all the suggested changes:
> >
> > - Replace ISC license by SPDX-License-Identifier header
> > - Fix units (milli- vs micro-) in comment about SNDIO_LATENCY_US
> > - Drop outdated comment about the "size" argument of
> > sndio_get_buffer_out()
> > - Fix AUDIO_FORMAT_U32 handling (missing "break" statement)
> > - Set {read,write] methods to audio_generic_{read,write} (fixes craches)
> > - Check if backend is enabled in sndio_poll_event()
> > - Use https://sndio.org in description
> > - Mark options as available after 7.0 release (instead of 6.2)
> > - Describe sndio-specific options (dev, latency) in qemu-options.hx
> > - Add myself as reviewer to MAINTAINERS
> > - Style fixes: no space after function names, use 4-space indent
> > - Don't use "return foo()" if foo() returns void
> > - Include backend to audio_drivers_priority[]
> >
> > Tested on OpenBSD, works as expected!
> >
> > MAINTAINERS | 5 +
> > audio/audio.c | 1 +
> > audio/audio_template.h | 2 +
> > audio/meson.build | 1 +
> > audio/sndioaudio.c | 555 +++++++++++++++++++++++++++++++++++++++++
> > meson.build | 9 +-
> > meson_options.txt | 4 +-
> > qapi/audio.json | 25 +-
> > qemu-options.hx | 16 ++
> > tests/vm/freebsd | 3 +
> > 10 files changed, 618 insertions(+), 3 deletions(-)
> > create mode 100644 audio/sndioaudio.c
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 7543eb4d59..76bdad064f 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -2307,6 +2307,7 @@ X: audio/jackaudio.c
> >
> > X: audio/ossaudio.c
> > X: audio/paaudio.c
> > X: audio/sdlaudio.c
> >
> > +X: audio/sndio.c
> >
> > X: audio/spiceaudio.c
> > F: qapi/audio.json
> >
> > @@ -2349,6 +2350,10 @@ R: Thomas Huth <huth@tuxfamily.org>
> >
> > S: Odd Fixes
> > F: audio/sdlaudio.c
> >
> > +Sndio Audio backend
> > +R: Alexandre Ratchov <alex@caoua.org>
> > +F: audio/sndio.c
> > +
>
> Thanks Alexandre for volunteering as reviewer!
>
> Gerd, would it be OK to set you as maintainer for now until new
> maintainer(s) adopt audio sections? Or should this start with "S: Orphan"
> instead?
Alexandre, if Gerd does not reply in a week or so, then please add "S: Orphan"
to MAINTAINERS for now to make it clear that there is no maintainer for sndio
yet to increase the chance for somebody to adopt it.
From Volker's response I assume you will be posting a v3 anyway.
If nobody takes care to queue your patch then let me know. Maybe I can push it
through my queue this time, provided that there are enough reviews. I also saw
your patch just by coincidence BTW, so please CC maintainers of affected files
as suggested by Volker.
Best regards,
Christian Schoenebeck
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] audio: Add sndio backend
2021-12-17 9:38 [PATCH v2] audio: Add sndio backend Alexandre Ratchov
` (2 preceding siblings ...)
2021-12-20 15:41 ` Christian Schoenebeck
@ 2021-12-23 15:10 ` WANG Xuerui
3 siblings, 0 replies; 8+ messages in thread
From: WANG Xuerui @ 2021-12-23 15:10 UTC (permalink / raw)
To: Alexandre Ratchov, qemu-devel; +Cc: Gerd Hoffmann, Brad
Hi Alexandre,
On 12/17/21 17:38, Alexandre Ratchov wrote:
> sndio is the native API used by OpenBSD, although it has been ported to
> other *BSD's and Linux (packages for Ubuntu, Debian, Void, Arch, etc.).
>
> Signed-off-by: Brad Smith <brad@comstyle.com>
> Signed-off-by: Alexandre Ratchov <alex@caoua.org>
> ---
>
> Thank you for the reviews and all the comments. Here's a second diff
> with all the suggested changes:
>
> - Replace ISC license by SPDX-License-Identifier header
> - Fix units (milli- vs micro-) in comment about SNDIO_LATENCY_US
> - Drop outdated comment about the "size" argument of sndio_get_buffer_out()
> - Fix AUDIO_FORMAT_U32 handling (missing "break" statement)
> - Set {read,write] methods to audio_generic_{read,write} (fixes craches)
> - Check if backend is enabled in sndio_poll_event()
> - Use https://sndio.org in description
> - Mark options as available after 7.0 release (instead of 6.2)
> - Describe sndio-specific options (dev, latency) in qemu-options.hx
> - Add myself as reviewer to MAINTAINERS
> - Style fixes: no space after function names, use 4-space indent
> - Don't use "return foo()" if foo() returns void
> - Include backend to audio_drivers_priority[]
>
> Tested on OpenBSD, works as expected!
>
> MAINTAINERS | 5 +
> audio/audio.c | 1 +
> audio/audio_template.h | 2 +
> audio/meson.build | 1 +
> audio/sndioaudio.c | 555 +++++++++++++++++++++++++++++++++++++++++
Here we can see the file added is named "sndioaudio.c", so...
> meson.build | 9 +-
> meson_options.txt | 4 +-
> qapi/audio.json | 25 +-
> qemu-options.hx | 16 ++
> tests/vm/freebsd | 3 +
> 10 files changed, 618 insertions(+), 3 deletions(-)
> create mode 100644 audio/sndioaudio.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 7543eb4d59..76bdad064f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2307,6 +2307,7 @@ X: audio/jackaudio.c
> X: audio/ossaudio.c
> X: audio/paaudio.c
> X: audio/sdlaudio.c
> +X: audio/sndio.c
it should say "sndioaudio.c" here...
> X: audio/spiceaudio.c
> F: qapi/audio.json
>
> @@ -2349,6 +2350,10 @@ R: Thomas Huth <huth@tuxfamily.org>
> S: Odd Fixes
> F: audio/sdlaudio.c
>
> +Sndio Audio backend
> +R: Alexandre Ratchov <alex@caoua.org>
> +F: audio/sndio.c
and here.
> +
> Block layer core
> M: Kevin Wolf <kwolf@redhat.com>
> M: Hanna Reitz <hreitz@redhat.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] audio: Add sndio backend
2021-12-20 15:41 ` Christian Schoenebeck
2021-12-23 13:00 ` Christian Schoenebeck
@ 2022-01-13 9:57 ` Gerd Hoffmann
1 sibling, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2022-01-13 9:57 UTC (permalink / raw)
To: Christian Schoenebeck; +Cc: Brad, qemu-devel, Alexandre Ratchov
On Mon, Dec 20, 2021 at 04:41:31PM +0100, Christian Schoenebeck wrote:
> On Freitag, 17. Dezember 2021 10:38:32 CET Alexandre Ratchov wrote:
> > sndio is the native API used by OpenBSD, although it has been ported to
> > other *BSD's and Linux (packages for Ubuntu, Debian, Void, Arch, etc.).
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 7543eb4d59..76bdad064f 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -2307,6 +2307,7 @@ X: audio/jackaudio.c
> > X: audio/ossaudio.c
> > X: audio/paaudio.c
> > X: audio/sdlaudio.c
> > +X: audio/sndio.c
> > X: audio/spiceaudio.c
> > F: qapi/audio.json
> >
> > @@ -2349,6 +2350,10 @@ R: Thomas Huth <huth@tuxfamily.org>
> > S: Odd Fixes
> > F: audio/sdlaudio.c
> >
> > +Sndio Audio backend
> > +R: Alexandre Ratchov <alex@caoua.org>
> > +F: audio/sndio.c
[ ... wading through my patch mail backlog ... ]
> Thanks Alexandre for volunteering as reviewer!
>
> Gerd, would it be OK to set you as maintainer for now until new maintainer(s)
> adopt audio sections? Or should this start with "S: Orphan" instead?
Yep, adding me is fine for now, although I can't promise timely
responses due to being quite busy with tianocore.
take care,
Gerd
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] audio: Add sndio backend
2021-12-19 21:07 ` Volker Rümelin
@ 2022-01-16 4:32 ` Brad Smith
0 siblings, 0 replies; 8+ messages in thread
From: Brad Smith @ 2022-01-16 4:32 UTC (permalink / raw)
To: Volker Rümelin, Alexandre Ratchov, Gerd Hoffmann; +Cc: qemu-devel
On 12/19/2021 4:07 PM, Volker Rümelin wrote:
> Hi Alexandre,
>
>> sndio is the native API used by OpenBSD, although it has been ported to
>> other *BSD's and Linux (packages for Ubuntu, Debian, Void, Arch, etc.).
>>
>> Signed-off-by: Brad Smith<brad@comstyle.com>
>> Signed-off-by: Alexandre Ratchov<alex@caoua.org>
>> ---
>>
>> Thank you for the reviews and all the comments. Here's a second diff
>> with all the suggested changes:
>>
>> - Replace ISC license by SPDX-License-Identifier header
>> - Fix units (milli- vs micro-) in comment about SNDIO_LATENCY_US
>> - Drop outdated comment about the "size" argument of
>> sndio_get_buffer_out()
>> - Fix AUDIO_FORMAT_U32 handling (missing "break" statement)
>> - Set {read,write] methods to audio_generic_{read,write} (fixes craches)
>> - Check if backend is enabled in sndio_poll_event()
>> - Usehttps://sndio.org in description
>> - Mark options as available after 7.0 release (instead of 6.2)
>> - Describe sndio-specific options (dev, latency) in qemu-options.hx
>> - Add myself as reviewer to MAINTAINERS
>> - Style fixes: no space after function names, use 4-space indent
>> - Don't use "return foo()" if foo() returns void
>> - Include backend to audio_drivers_priority[]
>>
>> Tested on OpenBSD, works as expected!
>>
>> MAINTAINERS | 5 +
>> audio/audio.c | 1 +
>> audio/audio_template.h | 2 +
>> audio/meson.build | 1 +
>> audio/sndioaudio.c | 555 +++++++++++++++++++++++++++++++++++++++++
>> meson.build | 9 +-
>> meson_options.txt | 4 +-
>
> I just noticed you changed meson_options.txt but you forgot to
> regenerate scripts/meson-buildoptions.sh with make update-buildoptions
> in your build directory. See docs/devel/build-system.rst.
My bad. That was me. We were discussing the diff before Alexandre posted
it. I was not sure
if the auto-generated file should be touched.
>
> And I'm still convinced you should CC all maintainers of the files
> this patch changes.
>
> With best regards,
> Volker
>
>> qapi/audio.json | 25 +-
>> qemu-options.hx | 16 ++
>> tests/vm/freebsd | 3 +
>> 10 files changed, 618 insertions(+), 3 deletions(-)
>>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2022-01-16 4:32 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-17 9:38 [PATCH v2] audio: Add sndio backend Alexandre Ratchov
2021-12-18 15:16 ` Volker Rümelin
2021-12-19 21:07 ` Volker Rümelin
2022-01-16 4:32 ` Brad Smith
2021-12-20 15:41 ` Christian Schoenebeck
2021-12-23 13:00 ` Christian Schoenebeck
2022-01-13 9:57 ` Gerd Hoffmann
2021-12-23 15:10 ` WANG Xuerui
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.