Re: [PATCH v2] audio/pwaudio.c: Add Pipewire audio backend for QEMU
> > BUFFER_SAMPLES is not used anywhere, and in code you are using 512 as > literals > instead. That was an oversight indeed, It's intended use was removed. s/buffer/ringbuffer/ maybe? > I think the naming convention 'buffer' is good. I would not use literals for period size and number of periods directly in > code. Better use macros or constants instead. > Noted, thanks. Why exactly 4k? > For playback streams, this size allows for more efficient streaming of audio data, as smaller chunks can lead to inaccuracies in sound quality. Why 44ms? > Thanks for spotting that, I had set its calculation to be Hz, because the default rate is between 44kHz to 48kHz, when actually the latency should be low as ~10ms latency (256 /48000 Hz). I would change that to 15ms which is fair for what a generic hardware can handle. BTW there's also the parameter to set the latency to desired value. On Thu, Feb 16, 2023 at 12:41 PM Christian Schoenebeck < qemu_...@crudebyte.com> wrote: > On Thursday, February 16, 2023 9:25:44 AM CET Dorinda Bassey wrote: > > This commit adds a new audiodev backend to allow QEMU to use Pipewire as > both an audio sink and source. > > > > Please wrap commit log. > > > Signed-off-by: Dorinda Bassey > > --- > > v2: > > * Shorten commit message > > * fix copyright ownership and authour > > * use QEMU standard of 4 space indentation > > * verbose use of pipewire instead pf pw > > > > audio/audio.c | 3 + > > audio/audio_template.h| 4 + > > audio/meson.build | 1 + > > audio/pwaudio.c | 818 ++ > > meson.build | 7 + > > meson_options.txt | 4 +- > > qapi/audio.json | 45 ++ > > qemu-options.hx | 17 + > > scripts/meson-buildoptions.sh | 8 +- > > 9 files changed, 904 insertions(+), 3 deletions(-) > > create mode 100644 audio/pwaudio.c > > > > diff --git a/audio/audio.c b/audio/audio.c > > index 4290309d18..aa55e41ad8 100644 > > --- a/audio/audio.c > > +++ b/audio/audio.c > > @@ -2069,6 +2069,9 @@ void audio_create_pdos(Audiodev *dev) > > #ifdef CONFIG_AUDIO_PA > > CASE(PA, pa, Pa); > > #endif > > +#ifdef CONFIG_AUDIO_PIPEWIRE > > +CASE(PIPEWIRE, pipewire, Pipewire); > > +#endif > > #ifdef CONFIG_AUDIO_SDL > > CASE(SDL, sdl, Sdl); > > #endif > > diff --git a/audio/audio_template.h b/audio/audio_template.h > > index 42b4712acb..0f02afb921 100644 > > --- a/audio/audio_template.h > > +++ b/audio/audio_template.h > > @@ -355,6 +355,10 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, > TYPE)(Audiodev *dev) > > case AUDIODEV_DRIVER_PA: > > return qapi_AudiodevPaPerDirectionOptions_base(dev->u.pa.TYPE); > > #endif > > +#ifdef CONFIG_AUDIO_PIPEWIRE > > +case AUDIODEV_DRIVER_PIPEWIRE: > > +return > qapi_AudiodevPipewirePerDirectionOptions_base(dev->u.pipewire.TYPE); > > +#endif > > #ifdef CONFIG_AUDIO_SDL > > case AUDIODEV_DRIVER_SDL: > > return > qapi_AudiodevSdlPerDirectionOptions_base(dev->u.sdl.TYPE); > > diff --git a/audio/meson.build b/audio/meson.build > > index 074ba9..65a49c1a10 100644 > > --- a/audio/meson.build > > +++ b/audio/meson.build > > @@ -19,6 +19,7 @@ foreach m : [ > >['sdl', sdl, files('sdlaudio.c')], > >['jack', jack, files('jackaudio.c')], > >['sndio', sndio, files('sndioaudio.c')], > > + ['pipewire', pipewire, files('pwaudio.c')], > >['spice', spice, files('spiceaudio.c')] > > ] > >if m[1].found() > > diff --git a/audio/pwaudio.c b/audio/pwaudio.c > > new file mode 100644 > > index 00..bb25133414 > > --- /dev/null > > +++ b/audio/pwaudio.c > > @@ -0,0 +1,818 @@ > > +/* > > + * QEMU Pipewire audio driver > > + * > > + * Copyright (c) 2023 Red Hat Inc. > > + * > > + * Author: Dorinda Bassey > > + * > > + * Permission is hereby granted, free of charge, to any person > obtaining a copy > > + * of this software and associated documentation files (the > "Software"), to deal > > + * in the Software without restriction, including without limitation > the rights > > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or > sell > > + * copies of the Software, and to permit persons to whom the Software is > > + * furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice shall be > included in > > + * all copies or substantial portions of the Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > MERCHANTABILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT > SHALL > > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR > OTHER > > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > ARISING FROM, > > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
Re: [PATCH v2] audio/pwaudio.c: Add Pipewire audio backend for QEMU
On Thursday, February 16, 2023 9:25:44 AM CET Dorinda Bassey wrote: > This commit adds a new audiodev backend to allow QEMU to use Pipewire as both > an audio sink and source. > Please wrap commit log. > Signed-off-by: Dorinda Bassey > --- > v2: > * Shorten commit message > * fix copyright ownership and authour > * use QEMU standard of 4 space indentation > * verbose use of pipewire instead pf pw > > audio/audio.c | 3 + > audio/audio_template.h| 4 + > audio/meson.build | 1 + > audio/pwaudio.c | 818 ++ > meson.build | 7 + > meson_options.txt | 4 +- > qapi/audio.json | 45 ++ > qemu-options.hx | 17 + > scripts/meson-buildoptions.sh | 8 +- > 9 files changed, 904 insertions(+), 3 deletions(-) > create mode 100644 audio/pwaudio.c > > diff --git a/audio/audio.c b/audio/audio.c > index 4290309d18..aa55e41ad8 100644 > --- a/audio/audio.c > +++ b/audio/audio.c > @@ -2069,6 +2069,9 @@ void audio_create_pdos(Audiodev *dev) > #ifdef CONFIG_AUDIO_PA > CASE(PA, pa, Pa); > #endif > +#ifdef CONFIG_AUDIO_PIPEWIRE > +CASE(PIPEWIRE, pipewire, Pipewire); > +#endif > #ifdef CONFIG_AUDIO_SDL > CASE(SDL, sdl, Sdl); > #endif > diff --git a/audio/audio_template.h b/audio/audio_template.h > index 42b4712acb..0f02afb921 100644 > --- a/audio/audio_template.h > +++ b/audio/audio_template.h > @@ -355,6 +355,10 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, > TYPE)(Audiodev *dev) > case AUDIODEV_DRIVER_PA: > return qapi_AudiodevPaPerDirectionOptions_base(dev->u.pa.TYPE); > #endif > +#ifdef CONFIG_AUDIO_PIPEWIRE > +case AUDIODEV_DRIVER_PIPEWIRE: > +return > qapi_AudiodevPipewirePerDirectionOptions_base(dev->u.pipewire.TYPE); > +#endif > #ifdef CONFIG_AUDIO_SDL > case AUDIODEV_DRIVER_SDL: > return qapi_AudiodevSdlPerDirectionOptions_base(dev->u.sdl.TYPE); > diff --git a/audio/meson.build b/audio/meson.build > index 074ba9..65a49c1a10 100644 > --- a/audio/meson.build > +++ b/audio/meson.build > @@ -19,6 +19,7 @@ foreach m : [ >['sdl', sdl, files('sdlaudio.c')], >['jack', jack, files('jackaudio.c')], >['sndio', sndio, files('sndioaudio.c')], > + ['pipewire', pipewire, files('pwaudio.c')], >['spice', spice, files('spiceaudio.c')] > ] >if m[1].found() > diff --git a/audio/pwaudio.c b/audio/pwaudio.c > new file mode 100644 > index 00..bb25133414 > --- /dev/null > +++ b/audio/pwaudio.c > @@ -0,0 +1,818 @@ > +/* > + * QEMU Pipewire audio driver > + * > + * Copyright (c) 2023 Red Hat Inc. > + * > + * Author: Dorinda Bassey > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > copy > + * of this software and associated documentation files (the "Software"), to > deal > + * in the Software without restriction, including without limitation the > rights > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > + * copies of the Software, and to permit persons to whom the Software is > + * furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > FROM, > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN > + * THE SOFTWARE. > + */ > + > +#include "qemu/osdep.h" > +#include "qemu/module.h" > +#include "audio.h" > +#include > +#include > +#include > +#include > + > +#include > + > +#define AUDIO_CAP "pipewire" > +#define RINGBUFFER_SIZE(1u << 22) > +#define RINGBUFFER_MASK(RINGBUFFER_SIZE - 1) > +#define BUFFER_SAMPLES128 BUFFER_SAMPLES is not used anywhere, and in code you are using 512 as literals instead. > + > +#include "audio_int.h" > + > +enum { > +MODE_SINK, > +MODE_SOURCE > +}; > + > +typedef struct pwaudio { > +Audiodev *dev; > +struct pw_thread_loop *thread_loop; > +struct pw_context *context; > + > +struct pw_core *core; > +struct spa_hook core_listener; > +int seq; > +} pwaudio; > + > +typedef struct PWVoice { > +pwaudio *g; > +bool enabled; > +struct pw_stream *stream; > +struct spa_hook stream_listener; > +struct spa_audio_info_raw info; > +uint32_t frame_size; > +struct spa_ringbuffer ring; > +uint8_t buffer[RINGBUFFER_SIZE]; s/buffer/ringbuffer/ maybe? > + > +uint32_t mode; > +struct pw_properties *props; > +} PWVoice; > + > +typedef
[PATCH v2] audio/pwaudio.c: Add Pipewire audio backend for QEMU
This commit adds a new audiodev backend to allow QEMU to use Pipewire as both an audio sink and source. Signed-off-by: Dorinda Bassey --- v2: * Shorten commit message * fix copyright ownership and authour * use QEMU standard of 4 space indentation * verbose use of pipewire instead pf pw audio/audio.c | 3 + audio/audio_template.h| 4 + audio/meson.build | 1 + audio/pwaudio.c | 818 ++ meson.build | 7 + meson_options.txt | 4 +- qapi/audio.json | 45 ++ qemu-options.hx | 17 + scripts/meson-buildoptions.sh | 8 +- 9 files changed, 904 insertions(+), 3 deletions(-) create mode 100644 audio/pwaudio.c diff --git a/audio/audio.c b/audio/audio.c index 4290309d18..aa55e41ad8 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -2069,6 +2069,9 @@ void audio_create_pdos(Audiodev *dev) #ifdef CONFIG_AUDIO_PA CASE(PA, pa, Pa); #endif +#ifdef CONFIG_AUDIO_PIPEWIRE +CASE(PIPEWIRE, pipewire, Pipewire); +#endif #ifdef CONFIG_AUDIO_SDL CASE(SDL, sdl, Sdl); #endif diff --git a/audio/audio_template.h b/audio/audio_template.h index 42b4712acb..0f02afb921 100644 --- a/audio/audio_template.h +++ b/audio/audio_template.h @@ -355,6 +355,10 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev) case AUDIODEV_DRIVER_PA: return qapi_AudiodevPaPerDirectionOptions_base(dev->u.pa.TYPE); #endif +#ifdef CONFIG_AUDIO_PIPEWIRE +case AUDIODEV_DRIVER_PIPEWIRE: +return qapi_AudiodevPipewirePerDirectionOptions_base(dev->u.pipewire.TYPE); +#endif #ifdef CONFIG_AUDIO_SDL case AUDIODEV_DRIVER_SDL: return qapi_AudiodevSdlPerDirectionOptions_base(dev->u.sdl.TYPE); diff --git a/audio/meson.build b/audio/meson.build index 074ba9..65a49c1a10 100644 --- a/audio/meson.build +++ b/audio/meson.build @@ -19,6 +19,7 @@ foreach m : [ ['sdl', sdl, files('sdlaudio.c')], ['jack', jack, files('jackaudio.c')], ['sndio', sndio, files('sndioaudio.c')], + ['pipewire', pipewire, files('pwaudio.c')], ['spice', spice, files('spiceaudio.c')] ] if m[1].found() diff --git a/audio/pwaudio.c b/audio/pwaudio.c new file mode 100644 index 00..bb25133414 --- /dev/null +++ b/audio/pwaudio.c @@ -0,0 +1,818 @@ +/* + * QEMU Pipewire audio driver + * + * Copyright (c) 2023 Red Hat Inc. + * + * Author: Dorinda Bassey + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "qemu/module.h" +#include "audio.h" +#include +#include +#include +#include + +#include + +#define AUDIO_CAP "pipewire" +#define RINGBUFFER_SIZE(1u << 22) +#define RINGBUFFER_MASK(RINGBUFFER_SIZE - 1) +#define BUFFER_SAMPLES128 + +#include "audio_int.h" + +enum { +MODE_SINK, +MODE_SOURCE +}; + +typedef struct pwaudio { +Audiodev *dev; +struct pw_thread_loop *thread_loop; +struct pw_context *context; + +struct pw_core *core; +struct spa_hook core_listener; +int seq; +} pwaudio; + +typedef struct PWVoice { +pwaudio *g; +bool enabled; +struct pw_stream *stream; +struct spa_hook stream_listener; +struct spa_audio_info_raw info; +uint32_t frame_size; +struct spa_ringbuffer ring; +uint8_t buffer[RINGBUFFER_SIZE]; + +uint32_t mode; +struct pw_properties *props; +} PWVoice; + +typedef struct PWVoiceOut { +HWVoiceOut hw; +PWVoice v; +} PWVoiceOut; + +typedef struct PWVoiceIn { +HWVoiceIn hw; +PWVoice v; +} PWVoiceIn; + +static void +stream_destroy(void *data) +{ +PWVoice *v = (PWVoice *) data; +spa_hook_remove(>stream_listener); +v->stream = NULL; +} + +/* output data processing function to read stuffs from the buffer */ +static void +playback_on_process(void *data) +{ +PWVoice *v = (PWVoice *) data; +void *p; +struct pw_buffer *b; +struct