Re: [PATCH v4] audio/pwaudio.c: Add Pipewire audio backend for QEMU

2023-02-27 Thread Marc-André Lureau
Hi

On Mon, Feb 27, 2023 at 4:27 PM Dorinda Bassey  wrote:
>>
>> Should be 8.0
>
> Wait, 8.0? The latest I can see so far is 7.2 or is there a specific page for 
> tracking the QEMU releases?

https://wiki.qemu.org/Planning/8.0
2023-03-07 Soft feature freeze. Only bug fixes after this point. All
feature changes must be already in a sub maintainer tree and all pull
requests from submaintainers must have been sent to the list by this
date.

Coming soon!

>
> On Sun, Feb 26, 2023 at 2:32 PM Marc-André Lureau 
>  wrote:
>>
>> Hi
>>
>> On Fri, Feb 17, 2023 at 9:08 PM Dorinda Bassey  wrote:
>> >
>> > This commit adds a new audiodev backend to allow QEMU to use Pipewire as
>> > both an audio sink and source. This backend is available on most systems
>> >
>> > Add Pipewire entry points for QEMU Pipewire audio backend
>> > Add wrappers for QEMU Pipewire audio backend in qpw_pcm_ops()
>> > qpw_write function returns the current state of the stream to pwaudio
>> > and Writes some data to the server for playback streams using pipewire
>> > spa_ringbuffer implementation.
>> > qpw_read function returns the current state of the stream to pwaudio and
>> > reads some data from the server for capture streams using pipewire
>> > spa_ringbuffer implementation. These functions qpw_write and qpw_read
>> > are called during playback and capture.
>> > Added some functions that convert pw audio formats to QEMU audio format
>> > and vice versa which would be needed in the pipewire audio sink and
>> > source functions qpw_init_in() & qpw_init_out().
>> > These methods that implement playback and recording will create streams
>> > for playback and capture that will start processing and will result in
>> > the on_process callbacks to be called.
>> > Built a connection to the Pipewire sound system server in the
>> > qpw_audio_init() method.
>> >
>> > Signed-off-by: Dorinda Bassey 
>>
>> pipewire: Initialize PW context
>> stream state: "connecting"
>> stream state: "connecting"
>> stream state: "paused"
>> node id: 125
>> stream state: "paused"
>> node id: 142
>> stream state: "streaming"
>> stream state: "streaming"
>>
>> Can you make it a bit silent? Probably all AUD_log() & printf*( should
>> be replaced by trace.
>>
>> Playback works for me, however recording is failing. I haven't
>> investigated, is it working for you?
>>
>> > ---
>> > fix typo
>> > raise version dependency
>> >
>> >  audio/audio.c |   3 +
>> >  audio/audio_template.h|   4 +
>> >  audio/meson.build |   1 +
>> >  audio/pwaudio.c   | 827 ++
>> >  meson.build   |   8 +
>> >  meson_options.txt |   4 +-
>> >  qapi/audio.json   |  45 ++
>> >  qemu-options.hx   |  17 +
>> >  scripts/meson-buildoptions.sh |   8 +-
>> >  9 files changed, 914 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..aa22f40a80
>> > --- /dev/null
>> > +++ b/audio/pwaudio.c
>> > @@ -0,0 +1,827 @@
>> > +/*
>> > + * QEMU Pipewire audio driver
>> > + *
>> > + * Copyright (c) 2023 Red Hat Inc.
>> > + *
>> > + * Author: Dorinda Bassey   
>> > + *
>> > + * Permission is hereby granted, free of charge, to any person obtaining 
>> >

Re: [PATCH v4] audio/pwaudio.c: Add Pipewire audio backend for QEMU

2023-02-27 Thread Dorinda Bassey
>
> Should be 8.0

Wait, 8.0? The latest I can see so far is 7.2 or is there a specific page
for tracking the QEMU releases?

On Sun, Feb 26, 2023 at 2:32 PM Marc-André Lureau <
marcandre.lur...@gmail.com> wrote:

> Hi
>
> On Fri, Feb 17, 2023 at 9:08 PM Dorinda Bassey  wrote:
> >
> > This commit adds a new audiodev backend to allow QEMU to use Pipewire as
> > both an audio sink and source. This backend is available on most systems
> >
> > Add Pipewire entry points for QEMU Pipewire audio backend
> > Add wrappers for QEMU Pipewire audio backend in qpw_pcm_ops()
> > qpw_write function returns the current state of the stream to pwaudio
> > and Writes some data to the server for playback streams using pipewire
> > spa_ringbuffer implementation.
> > qpw_read function returns the current state of the stream to pwaudio and
> > reads some data from the server for capture streams using pipewire
> > spa_ringbuffer implementation. These functions qpw_write and qpw_read
> > are called during playback and capture.
> > Added some functions that convert pw audio formats to QEMU audio format
> > and vice versa which would be needed in the pipewire audio sink and
> > source functions qpw_init_in() & qpw_init_out().
> > These methods that implement playback and recording will create streams
> > for playback and capture that will start processing and will result in
> > the on_process callbacks to be called.
> > Built a connection to the Pipewire sound system server in the
> > qpw_audio_init() method.
> >
> > Signed-off-by: Dorinda Bassey 
>
> pipewire: Initialize PW context
> stream state: "connecting"
> stream state: "connecting"
> stream state: "paused"
> node id: 125
> stream state: "paused"
> node id: 142
> stream state: "streaming"
> stream state: "streaming"
>
> Can you make it a bit silent? Probably all AUD_log() & printf*( should
> be replaced by trace.
>
> Playback works for me, however recording is failing. I haven't
> investigated, is it working for you?
>
> > ---
> > fix typo
> > raise version dependency
> >
> >  audio/audio.c |   3 +
> >  audio/audio_template.h|   4 +
> >  audio/meson.build |   1 +
> >  audio/pwaudio.c   | 827 ++
> >  meson.build   |   8 +
> >  meson_options.txt |   4 +-
> >  qapi/audio.json   |  45 ++
> >  qemu-options.hx   |  17 +
> >  scripts/meson-buildoptions.sh |   8 +-
> >  9 files changed, 914 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..aa22f40a80
> > --- /dev/null
> > +++ b/audio/pwaudio.c
> > @@ -0,0 +1,827 @@
> > +/*
> > + * 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

Re: [PATCH v4] audio/pwaudio.c: Add Pipewire audio backend for QEMU

2023-02-27 Thread Dorinda Bassey
>
> Can you make it a bit silent? Probably all AUD_log() & printf*( should
> be replaced by trace.

Yes it can be silent. It just made sense to me to have the output.

Playback works for me, however recording is failing. I haven't
> investigated, is it working for you?
>
I did check this and it seems playback for other audio backends are not
working either.
If I may ask what device options are you using for recording? I suspect
incorrect parameter configuration for recording on my end.

SPDX identifier instead would be neat
>
noted thanks.

Why that much?

 Because a larger ringbuffer size would help prevent buffer overruns which
could trigger seg faults. Also a larger size provides more flexibility for
handling data of various sizes/rates.

It looks like you don't take latency into account. Isn't there a more
> direct/simple pw push API that takes care of internal buffering? The
> intermediate ringbuffer is not nice to deal with.
>
The ringbuffer implementation is an essential component of the audio
processing pipeline, Pipewire minimizes latency by buffering audio data in
the ringbuffer. It is also designed to be thread-safe such that multiple
threads can access the buffer simultaneously without causing data
corruption or other issues.

Since it is not linux specific, no need to put it there. (filed
> alignment is kind of pointless to me)
>
 Agreed

Where is this latency value coming from?
>
Ah, I missed that. It's supposed to be 15000

Should be 8.0
>
Yes, Thanks.

On Sun, Feb 26, 2023 at 2:32 PM Marc-André Lureau <
marcandre.lur...@gmail.com> wrote:

> Hi
>
> On Fri, Feb 17, 2023 at 9:08 PM Dorinda Bassey  wrote:
> >
> > This commit adds a new audiodev backend to allow QEMU to use Pipewire as
> > both an audio sink and source. This backend is available on most systems
> >
> > Add Pipewire entry points for QEMU Pipewire audio backend
> > Add wrappers for QEMU Pipewire audio backend in qpw_pcm_ops()
> > qpw_write function returns the current state of the stream to pwaudio
> > and Writes some data to the server for playback streams using pipewire
> > spa_ringbuffer implementation.
> > qpw_read function returns the current state of the stream to pwaudio and
> > reads some data from the server for capture streams using pipewire
> > spa_ringbuffer implementation. These functions qpw_write and qpw_read
> > are called during playback and capture.
> > Added some functions that convert pw audio formats to QEMU audio format
> > and vice versa which would be needed in the pipewire audio sink and
> > source functions qpw_init_in() & qpw_init_out().
> > These methods that implement playback and recording will create streams
> > for playback and capture that will start processing and will result in
> > the on_process callbacks to be called.
> > Built a connection to the Pipewire sound system server in the
> > qpw_audio_init() method.
> >
> > Signed-off-by: Dorinda Bassey 
>
> pipewire: Initialize PW context
> stream state: "connecting"
> stream state: "connecting"
> stream state: "paused"
> node id: 125
> stream state: "paused"
> node id: 142
> stream state: "streaming"
> stream state: "streaming"
>
> Can you make it a bit silent? Probably all AUD_log() & printf*( should
> be replaced by trace.
>
> Playback works for me, however recording is failing. I haven't
> investigated, is it working for you?
>
> > ---
> > fix typo
> > raise version dependency
> >
> >  audio/audio.c |   3 +
> >  audio/audio_template.h|   4 +
> >  audio/meson.build |   1 +
> >  audio/pwaudio.c   | 827 ++
> >  meson.build   |   8 +
> >  meson_options.txt |   4 +-
> >  qapi/audio.json   |  45 ++
> >  qemu-options.hx   |  17 +
> >  scripts/meson-buildoptions.sh |   8 +-
> >  9 files changed, 914 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

Re: [PATCH v4] audio/pwaudio.c: Add Pipewire audio backend for QEMU

2023-02-26 Thread Marc-André Lureau
Hi

On Fri, Feb 17, 2023 at 9:08 PM Dorinda Bassey  wrote:
>
> This commit adds a new audiodev backend to allow QEMU to use Pipewire as
> both an audio sink and source. This backend is available on most systems
>
> Add Pipewire entry points for QEMU Pipewire audio backend
> Add wrappers for QEMU Pipewire audio backend in qpw_pcm_ops()
> qpw_write function returns the current state of the stream to pwaudio
> and Writes some data to the server for playback streams using pipewire
> spa_ringbuffer implementation.
> qpw_read function returns the current state of the stream to pwaudio and
> reads some data from the server for capture streams using pipewire
> spa_ringbuffer implementation. These functions qpw_write and qpw_read
> are called during playback and capture.
> Added some functions that convert pw audio formats to QEMU audio format
> and vice versa which would be needed in the pipewire audio sink and
> source functions qpw_init_in() & qpw_init_out().
> These methods that implement playback and recording will create streams
> for playback and capture that will start processing and will result in
> the on_process callbacks to be called.
> Built a connection to the Pipewire sound system server in the
> qpw_audio_init() method.
>
> Signed-off-by: Dorinda Bassey 

pipewire: Initialize PW context
stream state: "connecting"
stream state: "connecting"
stream state: "paused"
node id: 125
stream state: "paused"
node id: 142
stream state: "streaming"
stream state: "streaming"

Can you make it a bit silent? Probably all AUD_log() & printf*( should
be replaced by trace.

Playback works for me, however recording is failing. I haven't
investigated, is it working for you?

> ---
> fix typo
> raise version dependency
>
>  audio/audio.c |   3 +
>  audio/audio_template.h|   4 +
>  audio/meson.build |   1 +
>  audio/pwaudio.c   | 827 ++
>  meson.build   |   8 +
>  meson_options.txt |   4 +-
>  qapi/audio.json   |  45 ++
>  qemu-options.hx   |  17 +
>  scripts/meson-buildoptions.sh |   8 +-
>  9 files changed, 914 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..aa22f40a80
> --- /dev/null
> +++ b/audio/pwaudio.c
> @@ -0,0 +1,827 @@
> +/*
> + * 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
>

Re: [PATCH v4] audio/pwaudio.c: Add Pipewire audio backend for QEMU

2023-02-22 Thread Christian Schoenebeck
On Friday, February 17, 2023 6:07:32 PM CET Dorinda Bassey wrote:
> This commit adds a new audiodev backend to allow QEMU to use Pipewire as
> both an audio sink and source. This backend is available on most systems
> 
> Add Pipewire entry points for QEMU Pipewire audio backend
> Add wrappers for QEMU Pipewire audio backend in qpw_pcm_ops()
> qpw_write function returns the current state of the stream to pwaudio
> and Writes some data to the server for playback streams using pipewire
> spa_ringbuffer implementation.
> qpw_read function returns the current state of the stream to pwaudio and
> reads some data from the server for capture streams using pipewire
> spa_ringbuffer implementation. These functions qpw_write and qpw_read
> are called during playback and capture.
> Added some functions that convert pw audio formats to QEMU audio format
> and vice versa which would be needed in the pipewire audio sink and
> source functions qpw_init_in() & qpw_init_out().
> These methods that implement playback and recording will create streams
> for playback and capture that will start processing and will result in
> the on_process callbacks to be called.
> Built a connection to the Pipewire sound system server in the
> qpw_audio_init() method.
> 
> Signed-off-by: Dorinda Bassey 

Acked-by: Christian Schoenebeck 

> ---
> fix typo
> raise version dependency
> 
>  audio/audio.c |   3 +
>  audio/audio_template.h|   4 +
>  audio/meson.build |   1 +
>  audio/pwaudio.c   | 827 ++
>  meson.build   |   8 +
>  meson_options.txt |   4 +-
>  qapi/audio.json   |  45 ++
>  qemu-options.hx   |  17 +
>  scripts/meson-buildoptions.sh |   8 +-
>  9 files changed, 914 insertions(+), 3 deletions(-)
>  create mode 100644 audio/pwaudio.c





[PATCH v4] audio/pwaudio.c: Add Pipewire audio backend for QEMU

2023-02-17 Thread Dorinda Bassey
This commit adds a new audiodev backend to allow QEMU to use Pipewire as
both an audio sink and source. This backend is available on most systems

Add Pipewire entry points for QEMU Pipewire audio backend
Add wrappers for QEMU Pipewire audio backend in qpw_pcm_ops()
qpw_write function returns the current state of the stream to pwaudio
and Writes some data to the server for playback streams using pipewire
spa_ringbuffer implementation.
qpw_read function returns the current state of the stream to pwaudio and
reads some data from the server for capture streams using pipewire
spa_ringbuffer implementation. These functions qpw_write and qpw_read
are called during playback and capture.
Added some functions that convert pw audio formats to QEMU audio format
and vice versa which would be needed in the pipewire audio sink and
source functions qpw_init_in() & qpw_init_out().
These methods that implement playback and recording will create streams
for playback and capture that will start processing and will result in
the on_process callbacks to be called.
Built a connection to the Pipewire sound system server in the
qpw_audio_init() method.

Signed-off-by: Dorinda Bassey 
---
fix typo
raise version dependency

 audio/audio.c |   3 +
 audio/audio_template.h|   4 +
 audio/meson.build |   1 +
 audio/pwaudio.c   | 827 ++
 meson.build   |   8 +
 meson_options.txt |   4 +-
 qapi/audio.json   |  45 ++
 qemu-options.hx   |  17 +
 scripts/meson-buildoptions.sh |   8 +-
 9 files changed, 914 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..aa22f40a80
--- /dev/null
+++ b/audio/pwaudio.c
@@ -0,0 +1,827 @@
+/*
+ * 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_SAMPLES512
+
+#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;