[PATCH 2/4] conf: allow to map sound device to host device

Roman Bogorodskiy bogorodskiy at gmail.com
Wed Jul 22 14:41:00 UTC 2020


  Daniel P. Berrangé wrote:

> On Sat, Jul 18, 2020 at 04:31:16PM +0400, Roman Bogorodskiy wrote:
> > Extend <sound> device element to accept "soundDevice"
> > sub-element which allows to map guest sound device to host
> > sound device.
> > 
> > Example
> > 
> >   <sound model='ich6'>
> >     <soundDevice playback='/dev/dsp0' recording='/dev/dsp0'/>
> >   </sound>
> 
> IIUC, FreeBSD's audio subsystem is the classic OSS API ?

The sound(4) manpage[1] claims it supports most of the OSS ioctls().

> 
> > 
> > The "playback" attribute points to the playback device,
> > and "recording" attribute points to the recording device.
> 
> I'm thinking about how we'll have to deal with QEMU's sound backend
> options, and alignment with BHyve / FreeBSD.
> 
> In QEMU there are multiple backends, OSS, ALSA, PulseAudio, SPICE,
> VNC, and many more. The backends have many properties, and many
> of the properties can be set separately for input and output.
> 
> IIUC, QEMU can expose multiple sound devices to the guest too.
> 
> I think this means that we can have a M:N relationship between
> a sound device, and an audio backend, not just 1:1.
> 
> Assuming I'm right about the M:N relationship, I assume that
> of multiple cards all do playback concurrently, something
> will have todo mixing of the streams ?  How will that work
> with audio capture, is only one card allowed to capture at
> any time ?

In case of FreeBSD, the sound driver does mixing on its own, i.e.
you can boot multiple guests pointed to /dev/dsp0 and audio streams from
these guests will be played properly.

I didn't test capturing though.

> I'm copying Gerd to confirm the above...
> 
> Anyway, if we have M:N relation, then we'll need separate
> configuration elements.
> 
> So I think we'd need to allow something like this:
> 
>    <sound model='ich6'>
>      <audio id="audio0"/>
>    </sound>
> 
>    <sound model='ich6'>
>      <audio id="audio1"/>
>    </sound>
> 
>    <sound model='ich6'>
>      <audio id="audio1"/>
>    </sound>
> 
>    <audio type="oss" id="audio0">
>      <input dev='/dev/dsp0'/>
>      <output dev='/dev/dsp0'/>
>    </audio>
> 
>    <audio type="spice" id="audio1"/>
> 
> 
> Here we have one sound device connected to OSS, and two sound
> devices connected to SPICE. 
> 
> > 
> > Signed-off-by: Roman Bogorodskiy <bogorodskiy at gmail.com>
> > ---
> >  docs/schemas/domaincommon.rng | 15 +++++++++++++++
> >  src/conf/domain_conf.c        | 24 ++++++++++++++++++++++++
> >  src/conf/domain_conf.h        |  3 +++
> >  3 files changed, 42 insertions(+)
> > 
> > diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> > index a810f569c6..b11b3f2af6 100644
> > --- a/docs/schemas/domaincommon.rng
> > +++ b/docs/schemas/domaincommon.rng
> > @@ -4346,6 +4346,18 @@
> >        </attribute>
> >      </element>
> >    </define>
> > +  <define name="soundDevice">
> > +    <element name="soundDevice">
> > +       <attribute name="playback">
> > +         <text/>
> > +       </attribute>
> > +       <optional>
> > +         <attribute name="recording">
> > +           <text/>
> > +         </attribute>
> > +       </optional>
> > +    </element>
> > +  </define>
> >    <define name="sound">
> >      <element name="sound">
> >        <attribute name="model">
> > @@ -4366,6 +4378,9 @@
> >          <optional>
> >            <ref name="address"/>
> >          </optional>
> > +	<optional>
> > +	  <ref name="soundDevice"/>
> > +	</optional>
> >          <zeroOrMore>
> >            <ref name="codec"/>
> >          </zeroOrMore>
> > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> > index 7ecd2818b9..b678a2319d 100644
> > --- a/src/conf/domain_conf.c
> > +++ b/src/conf/domain_conf.c
> > @@ -2850,6 +2850,9 @@ void virDomainSoundDefFree(virDomainSoundDefPtr def)
> >          virDomainSoundCodecDefFree(def->codecs[i]);
> >      VIR_FREE(def->codecs);
> >  
> > +    VIR_FREE(def->playback);
> > +    VIR_FREE(def->recording);
> > +
> >      VIR_FREE(def);
> >  }
> >  
> > @@ -14984,6 +14987,8 @@ virDomainSoundDefParseXML(virDomainXMLOptionPtr xmlopt,
> >      virDomainSoundDefPtr def;
> >      VIR_XPATH_NODE_AUTORESTORE(ctxt);
> >      g_autofree char *model = NULL;
> > +    char *recording = NULL;
> > +    xmlNodePtr soundDeviceNode;
> >  
> >      if (VIR_ALLOC(def) < 0)
> >          return NULL;
> > @@ -15024,6 +15029,14 @@ virDomainSoundDefParseXML(virDomainXMLOptionPtr xmlopt,
> >          }
> >      }
> >  
> > +    soundDeviceNode = virXPathNode("./soundDevice", ctxt);
> > +    if (soundDeviceNode) {
> > +        def->playback = virXMLPropString(soundDeviceNode, "playback");
> > +        recording = virXMLPropString(soundDeviceNode, "recording");
> > +        if (recording)
> > +            def->recording = recording;
> > +    }
> > +
> >      if (virDomainDeviceInfoParseXML(xmlopt, node, &def->info, flags) < 0)
> >          goto error;
> >  
> > @@ -15056,6 +15069,9 @@ virDomainSoundDefEquals(const virDomainSoundDef *a,
> >          !virDomainDeviceInfoAddressIsEqual(&a->info, &b->info))
> >          return false;
> >  
> > +    if ((a->playback != b->playback) || (a->recording != b->recording))
> > +        return false;
> > +
> >      return true;
> >  }
> >  
> > @@ -27284,6 +27300,14 @@ virDomainSoundDefFormat(virBufferPtr buf,
> >      for (i = 0; i < def->ncodecs; i++)
> >          virDomainSoundCodecDefFormat(&childBuf, def->codecs[i]);
> >  
> > +    if (def->playback) {
> > +        virBufferAsprintf(&childBuf, "<soundDevice playback='%s'", def->playback);
> > +        if (def->recording)
> > +            virBufferAsprintf(&childBuf, " recording='%s'/>\n", def->recording);
> > +        else
> > +            virBufferAddLit(&childBuf, "/>\n");
> > +    }
> > +
> >      if (virDomainDeviceInfoFormat(&childBuf, &def->info, flags) < 0)
> >          return -1;
> >  
> > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> > index 241149af24..b501f48442 100644
> > --- a/src/conf/domain_conf.h
> > +++ b/src/conf/domain_conf.h
> > @@ -1415,6 +1415,9 @@ struct _virDomainSoundDef {
> >  
> >      size_t ncodecs;
> >      virDomainSoundCodecDefPtr *codecs;
> > +
> > +    char *playback;
> > +    char *recording;
> >  };
> >  
> >  typedef enum {
> > -- 
> > 2.27.0
> > 
> 
> Regards,
> Daniel
> -- 
> |: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org         -o-            https://fstop138.berrange.com :|
> |: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
> 

Roman Bogorodskiy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20200722/7e09cf32/attachment-0001.sig>


More information about the libvir-list mailing list